2014-09-26 57 views
4

AsyncTaskCodeActivity在执行第一个await后访问上下文参数时失败。例如:AsyncTaskCodeActivity和等待后丢失的上下文

public class TestAsyncTaskCodeActivity : AsyncTaskCodeActivity<int> 
{ 
    protected async override Task<int> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) 
    { 
     await Task.Delay(50); 
     // context has already been disposed and the next line throws 
     // ObjectDisposedException with the message: 
     // An ActivityContext can only be accessed within the scope of the function it was passed into. 
     context.Track(new CustomTrackingRecord("test")); 
     // more awaits can happen here 
     return 3; 
    } 
} 

是否有任何简单的方法来保存上下文,以便在等待某些内容后也可以使用它?

回答

6

啊。

当我写AsyncTaskCodeActivity<T>时,我认为AsyncCodeActivityContext事实上将在异步方法的开始和结束时是相同的实例,并且一直可用。情况并非如此(这有点奇怪 - 不知道为什么WF团队做出了这个决定)。

相反,AsyncCodeActivityContext可以可以在活动的开始和结束访问。的确很尴尬。

下面更新后的代码将允许您在开始时访问上下文(例如,读取In变量),然后在最后再次访问上下文。我还介绍了一个可选的TState,它可以用于存储活动状态(活动可以在其执行过程中访问)。让我知道这是否符合您的需求;我没有测试过它。

public abstract class AsyncTaskCodeActivity<T, TState> : AsyncCodeActivity<T> 
{ 
    protected sealed override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state) 
    { 
    TState activityState = PreExecute(context); 
    context.UserState = activityState; 
    var task = ExecuteAsync(activityState); 
    return AsyncFactory<T>.ToBegin(task, callback, state); 
    } 

    protected sealed override T EndExecute(AsyncCodeActivityContext context, IAsyncResult asyncResult) 
    { 
    var result = AsyncFactory<T>.ToEnd(asyncResult); 
    return PostExecute(context, (TState)context.UserState, result); 
    } 

    protected virtual TState PreExecute(AsyncCodeActivityContext context) 
    { 
    return default(TState); 
    } 
    protected abstract Task<T> ExecuteAsync(TState activityState); 
    protected virtual T PostExecute(AsyncCodeActivityContext context, TState activityState, T result) 
    { 
    return result; 
    } 
} 
public abstract class AsyncTaskCodeActivity<T> : AsyncTaskCodeActivity<T, object> 
{ 
} 
+0

谢谢。我有一个类似的想法,但无法创建良好的实施。但是这个解决方案仍然有严重的局限我想过使用[AsyncNativeActivity](http://blogs.msdn.com/b/tilovell/archive/2011/06/09/wf4-they-have-asynccodeactivity-why-not-asyncnativeactivity.aspx)和一个自定义调度程序以便始终访问上下文。你怎么看? – arturek 2014-10-13 06:17:33

+1

有什么限制? – 2014-10-17 18:34:42

+0

自从你发布了这个版本已经过去了一年,但我在玩同样的问题。任何想法如何在这个游戏中正确处理ExecutionContext? – wasabi 2015-12-21 02:28:10