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