QueueBackgroundWorkItem

QueueBackgroundWorkItem

我需要在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/

10-10 00:01