use*_*958 30 c# task task-parallel-library async-await
如果任何正在运行的任务抛出异常,我想让Task.WaitAll()爆发,这样我就不必等待60秒才能完成.我该如何实现这种行为?如果WaitAll()无法实现,那么还有其他c#功能或解决方法吗?
Task task1 = Task.Run(() => throw new InvalidOperationException());
Task task2 = ...
...
try
{
Task.WaitAll(new Task[]{task1, task2, ...}, TimeSpan.FromSeconds(60));
}
catch (AggregateException)
{
// If any exception thrown on any of the tasks, break out immediately instead of wait all the way to 60 seconds.
}
Run Code Online (Sandbox Code Playgroud)
nos*_*tio 18
以下应该在不更改原始任务的代码(未经测试)的情况下执行此操作:
static bool WaitAll(Task[] tasks, int timeout, CancellationToken token)
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(token);
var proxyTasks = tasks.Select(task =>
task.ContinueWith(t => {
if (t.IsFaulted) cts.Cancel();
return t;
},
cts.Token,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Current).Unwrap());
return Task.WaitAll(proxyTasks.ToArray(), timeout, cts.Token);
}
Run Code Online (Sandbox Code Playgroud)
请注意,它只跟踪故障任务(投掷的任务).如果您还需要跟踪已取消的任务,请进行以下更改:
if (t.IsFaulted || t.IsCancelled) cts.Cancel();
Run Code Online (Sandbox Code Playgroud)
更新,等待任务代理在这里是多余的,正如@svick在评论中所指出的那样.他提出了一个改进的版本:https://gist.github.com/svick/9992598.