c# - 在 QueueBackgroundWorkItem 上实现 WhenAll

标签 c# asp.net-web-api

我需要在 ASP.NET WebAPI 中生成一些长时间运行的任务,我选择使用 QueueBackgroundWorkItem 来实现。

我的问题是 -

我需要为这些任务实现一个 WhenAll 机制,这意味着 - 我需要知道一些任务何时完成,然后执行其他一些任务。

如何使用 QueueBackgroundWorkItem 来完成?我找不到这样做的方法,因为它返回 void,并接受 Action

谢谢!

最佳答案

您可以使用 TaskCompletionSource创建这样的辅助方法:

public static Task RunViaQueueBackgroundWorkItem(Action<CancellationToken> action)
{
    TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
    HostingEnvironment.QueueBackgroundWorkItem((ct) =>
    {
        try
        {
            action(ct);

            if (ct.IsCancellationRequested)
                tcs.TrySetCanceled();
            else
                tcs.TrySetResult(0);
        }
        catch (Exception ex)
        {
            tcs.TrySetException(ex);
        }
    });

    return tcs.Task;
}

此方法将返回一个任务,该任务将在操作完成后完成。请注意,它处理在调用操作期间发生异常的情况。如果请求取消,它也会处理这种情况。

这是一个如何使用它的例子:

public async Task<string> Get(int id)
{
    var t1 = RunViaQueueBackgroundWorkItem(ct => DoSomeTask1(ct));
    var t2 = RunViaQueueBackgroundWorkItem(ct => DoSomeTask2(ct));

    await Task.WhenAll(t1, t2);

    //...
}

为了完整起见,这里是 QueueBackgroundWorkItem 的另一个重载的辅助方法:

public static Task RunViaQueueBackgroundWorkItem(Func<CancellationToken,Task> asyncAction)
{
    TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
    HostingEnvironment.QueueBackgroundWorkItem(async (ct) => 
    {
        try
        {
            await asyncAction(ct);

            if (ct.IsCancellationRequested)
                tcs.TrySetCanceled();
            else
                tcs.TrySetResult(0);
        }
        catch (Exception ex)
        {
            tcs.TrySetException(ex);
        }
    });

    return tcs.Task;
}

关于c# - 在 QueueBackgroundWorkItem 上实现 WhenAll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38039945/

相关文章:

c# - 基于列以编程方式在共享点中创建 TreeView

amazon-web-services - AWS Lambda - 使用 .NET Core 构建无服务器 API

c# - 将参数设置为 asp.net WebAPI URL

c# - 将对象序列化为已包含一个 JSON 属性的 JSON

c# - 在 Azure 移动服务中找不到属性 nameId

java - 如何在 java 或 c# 中强制执行 ddd 聚合?

c# - 如何从父对象的DataContext中读取属性?

c# - CollectionViewSource.GetDefaultView 在 SetBinding 之后返回 null

c# - 从 DateTimeOffset 中删除时区偏移量?

c# - WebApi.UnityDependencyResolver 没有实现 Microsoft.Practices.ServiceLocation.IServiceLocator。参数 : commonServiceLocator