[英]System.AggregateException on Task.WaitAll
I have the following code which is firing off a number of async Task. 我有以下代码触发了许多异步任务。
List<TimeoutException> TimeoutExceptions = new List<TimeoutException>();
List<TaskCanceledException> TaskCanceledExceptions = new List<TaskCanceledException>();
List<Exception> Exceptions = new List<Exception>();
List<AggregateException> AggregateExceptions = new List<AggregateException>();
List<Models.Channel.IChannel> channels = new List<Models.Channel.IChannel>();
channels.Add(new Models.Channel.DummyChannelName());
var tasks = new List<Task>();
foreach (Models.Channel.IChannel channel in channels)
{
try
{
var cts = new CancellationTokenSource();
cts.CancelAfter(channel.TimeOut);
tasks.Add(Task.Run(() =>
{
channel.Data = channel.RequestOffers(new Models.Request.AvailabilityRequest()).Result;
if (cts.Token.IsCancellationRequested)
cts.Token.ThrowIfCancellationRequested();
}, cts.Token));
}
catch (TimeoutException t)
{
TimeoutExceptions.Add(t);
}
catch (TaskCanceledException tc)
{
TaskCanceledExceptions.Add(tc);
}
catch (AggregateException ae)
{
AggregateExceptions.Add(ae);
}
catch(Exception ex)
{
Exceptions.Add(ex);
}
}
Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(5));
The problem I have is that if a task is cancelled because of a timeout I'm getting the following exception 我的问题是,如果由于超时而取消任务,我将得到以下异常
<ExceptionMessage>One or more errors occurred.</ExceptionMessage>
<ExceptionType>System.AggregateException</ExceptionType>
Is it just a simple case that I need a Try Catch around Task.WaitAll, or should my code be structured differently. 我是否需要围绕Task.WaitAll进行Try Catch只是一种简单的情况,还是应该以不同的方式构造我的代码?
If an exception occurs inside a task the exception is raised on the calling thread when you Wait
for a task. 如果任务内发生异常,则在Wait
任务时会在调用线程上引发异常。 If a task is sucessfully created all exceptions that occur inside the task are wrapped in an AggregateException
and thrown on the wait. 如果成功创建了任务,则该任务内部发生的所有异常都将包装在AggregateException
并在等待时抛出。
For you example this means you can remove the try/catch block within your loop and use it to wrap the Task.WaitAll(...)
after the loop. 对于您的示例,这意味着您可以在循环内删除try / catch块,并在循环后使用它包装Task.WaitAll(...)
。
var tasks = new List<Task>();
foreach (Models.Channel.IChannel channel in channels)
{
Task myTask = Task.Run(...); // create your task here
tasks.Add(myTask);
}
try
{
Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(5));
}
catch
{
// Insert Exception handling logic
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.