创建一个简单的异步工作流 Activity

Creating a simple Async Workflow Activity

我正在努力学习工作流基础,但显然我似乎连异步 activity 的最基本实现都无法正常工作。

任何人都可以用这个 activity 为我指出正确的方向,我已经把它放在一起以便使用 HttpClient 发出异步 OData 请求 ...

首先,我创建了一个从 AsyncCodeActivity 扩展的基类型 ...

public abstract class ODataActivity<TResult> : AsyncCodeActivity<TResult>, IDisposable
{
    protected HttpClient Api =
        new HttpClient(
            new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }
        )
        { BaseAddress = new Uri(new Config().ApiRoot) };

    bool disposed = false;

    public void Dispose()
    {
        Dispose(disposed);
    }

    public virtual void Dispose(bool disposed)
    {
        if (!disposed)
        {
            Api.Dispose();
            Api = null;
        }
    }
}

接下来我继承它以提供我的实现...

public class ODataFetchActivity<TResult> : ODataActivity<TResult>
{
    public string Query { get; set; }

    protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
    {
        var task = Api.GetAsync(Query)
            .ContinueWith(t => t.Result.Content.ReadAsAsync<TResult>())
            .ContinueWith(t => callback(t));

        context.UserState = task;
        return task;
    }

    protected override TResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
    {
        var response = ((Task<TResult>)result).Result;
        context.SetValue(Result, response);
        return response;
    }
}

... 这个 activity 只能获取请求的想法,然后我可以实现一个 post,放置和删除以在我的顶部以相同的方式获得完整的 crud上面的基本类型。

当我将其添加到工作流并尝试在新的 wpf 应用程序中使用重新托管的设计器执行流程时,问题就出现了,导致以下异常...

编辑:

所以我做了更多的修补,并且有一些似乎没有抱怨的东西,但我不相信这是一个 "good" 处理这个问题的方法,因为 Task 直接实现 IAsyncResult,感觉就像我'我跳过了一堆我可能不需要的箍。

public class ODataFetchActivity<TResult> : ODataActivity<TResult>
{
    public string Query { get; set; }

    Func<TResult> work;

    protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
    {
        work = () => Api.Get<TResult>(Query).Result;
        context.UserState = work;
        return work.BeginInvoke(callback, state);
    }

    protected override TResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
    {
        TResult response = work.EndInvoke(result);
        Result.Set(context, response);
        return response;
    }
}

这似乎可以编译 运行 但我忍不住觉得有一种更简洁的方法来处理这个问题。

嗯,显然这很好用...

public class ODataFetchActivity<TResult> : ODataActivity<TResult>
{
    public string Query { get; set; }

    Func<TResult> work;

    protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
    {
        work = () => Api.Get<TResult>(Query).Result;
        context.UserState = work;
        return work.BeginInvoke(callback, state);
    }

    protected override TResult EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
    {
        TResult response = work.EndInvoke(result);
        Result.Set(context, response);
        return response;
    }
}

我从设计者那里得到了一些奇怪的行为,它会 运行 以前的版本,直到保存(不知道为什么)