async-await - AsyncTaskCodeActivity 和等待后丢失的上下文

标签 async-await workflow-foundation-4

在执行第一次等待后访问上下文参数时,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;
    }
}

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

最佳答案

啊。

当我写 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>
{
}

关于async-await - AsyncTaskCodeActivity 和等待后丢失的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26054585/

相关文章:

c# - 延迟 ContinueWith 不起作用

vb.net - LINQ to Entities 无法识别方法 [Type] GetValue [Type]

workflow-foundation-4 - 在执行之前确定运行时的工作流程参数

workflow - 在自定义事件设计器中将数据绑定(bind)到组合框

c# - WPF WF4.5 Rehosted Designer 内存问题

c# - 是否可以在工作流之外获取 ActivityContext?

javascript - Promise 无法通过 setTimeOut 的递归函数解析

c# - 如何在基于异步/等待的单线程协程实现中捕获异常

Javascript 无法将 Vars/Fn 传递给 .evaluate() 作用域 (NightmareJS)

javascript - 为什么我不能直接在SetTimeout函数中调用resolve()来处理Promises