Create a asynchronous activity in WF4

在WF中创建一个异步执行的activity,可以直接继承抽象类AsyncCodeActivity或者在NativeActivity使用bookmark实现。

AsyncCodeActivity:

protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)

protected override void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)

protected override void Cancel(AsyncCodeActivityContext context)

除了定义委托,也可以调用.NET类的异步方法,比如FileStream.BeginWrite()/EndWrite(), FileStream的实例通过AsyncCodeActivityContext.UserState传递

AsyncCodeActivity中的参数不能直接在委托中使用,可以通过参数的方式传给委托

AsyncCodeActivity不对持schedule Action或child activity,可以组合一个异步执行的活动在其他普通活动中。

http://msdn.microsoft.com/en-us/library/ee358731.aspx

NativeActivity:

public class BookmarkResumptionHelper : IWorkflowInstanceExtension
 
{
 
    private WorkflowInstanceProxy instance;
 
 
 
    public void ResumeBookmark(Bookmark bookmark, object value)
 
    {
 
        this.instance.EndResumeBookmark(
 
            this.instance.BeginResumeBookmark(bookmark, value, null, null));
 
    }
 
 
 
    IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
 
    {
 
        yield break;
 
    }
 
 
 
    void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance)
 
    {
 
        this.instance = instance;
 
    }
 
}
 
 
 
public abstract class AsyncNativeActivity : NativeActivity
 
{
 
    private Variable<NoPersistHandle> NoPersistHandle { get; set; }
 
    private Variable<Bookmark> Bookmark { get; set; }
 
 
 
    protected override bool CanInduceIdle
 
    {
 
        get
 
        {
 
            return true; // we create bookmarks
 
        }
 
    }
 
 
 
    protected abstract IAsyncResult BeginExecute(
 
        NativeActivityContext context, 

        AsyncCallback callback, object state);
 
 
 
    protected abstract void EndExecute(
 
        NativeActivityContext context, 

        IAsyncResult result);
 
 
 
    protected override void Execute(NativeActivityContext context)
 
    {
 
        var noPersistHandle = NoPersistHandle.Get(context);
 
        noPersistHandle.Enter(context);
 
 
 
        var bookmark = context.CreateBookmark(BookmarkResumptionCallback);
 
        this.Bookmark.Set(context, bookmark);
 
 
 
        BookmarkResumptionHelper helper = context.GetExtension<BookmarkResumptionHelper>();
 
        Action<IAsyncResult> resumeBookmarkAction = (result) =>
 
        {
 
            helper.ResumeBookmark(bookmark, result);
 
        };
 
 
 
        IAsyncResult asyncResult = this.BeginExecute(context, AsyncCompletionCallback, resumeBookmarkAction);
 
 
 
        if (asyncResult.CompletedSynchronously)
 
        {
 
            noPersistHandle.Exit(context);
 
            context.RemoveBookmark(bookmark);
 
            EndExecute(context, asyncResult);
 
        }
 
    }
 
 
 
    private void AsyncCompletionCallback(IAsyncResult asyncResult)
 
    {
 
        if (!asyncResult.CompletedSynchronously)
 
        {
 
            Action<IAsyncResult> resumeBookmark = asyncResult.AsyncState as Action<IAsyncResult>;
 
            resumeBookmark.Invoke(asyncResult);
 
        }
 
    }
 
 
 
    private void BookmarkResumptionCallback(NativeActivityContext context, Bookmark bookmark, object value)
 
    {
 
        var noPersistHandle = NoPersistHandle.Get(context);
 
        noPersistHandle.Exit(context);
 
        // unnecessary since it's not multiple resume: 

        // context.RemoveBookmark(bookmark);
 
 
 
        IAsyncResult asyncResult = value as IAsyncResult;
 
        this.EndExecute(context, asyncResult);
 
    }
 
 
 
    protected override void CacheMetadata(NativeActivityMetadata metadata)
 
    {
 
        this.NoPersistHandle = new Variable<NoPersistHandle>();
 
        this.Bookmark = new Variable<Bookmark>();
 
        metadata.AddImplementationVariable(this.NoPersistHandle);
 
        metadata.AddImplementationVariable(this.Bookmark);
 
        metadata.RequireExtension<BookmarkResumptionHelper>();
 
        metadata.AddDefaultExtensionProvider<BookmarkResumptionHelper>(() => new BookmarkResumptionHelper());
 
    }
 
}

http://blogs.msdn.com/b/tilovell/archive/2011/06/14/10172794.aspx

 

http://blogs.msdn.com/b/rjacobs/archive/2011/06/23/windows-workflow-foundation-wf4-activities-and-threads.aspx

 

posted @ 2012-06-04 16:09  Leo Tang  阅读(569)  评论(0)    收藏  举报