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;
}
}
有没有简单的方法来保存上下文,以便在等待之后也可以使用它?
答案 0 :(得分:6)
阿
当我写AsyncTaskCodeActivity<T>
时,我假设AsyncCodeActivityContext
实际上在异步方法的开头和结尾都是同一个实例,并且一直可用。事实并非如此(这有点奇怪 - 不确定为什么WF团队做出了这个决定)。
相反,AsyncCodeActivityContext
只能在活动的开头和结尾访问 。确实很尴尬。
下面更新的代码将允许您在开头访问上下文(例如,读取变量),然后在最后再次访问上下文。我还引入了一个可选的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>
{
}