【问题标题】:System.AggregateException on Task.WaitAllTask.WaitAll 上的 System.AggregateException
【发布时间】:2019-01-13 15:17:57
【问题描述】:

我有以下代码触发了一些异步任务。

        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));

我遇到的问题是,如果任务由于超时而被取消,我会收到以下异常

<ExceptionMessage>One or more errors occurred.</ExceptionMessage>
<ExceptionType>System.AggregateException</ExceptionType>

这只是一个简单的案例,我需要围绕 Task.WaitAll 进行 Try Catch,还是我的代码结构应该不同。

【问题讨论】:

  • 如果我多次调用 Task.WaitAll 是否有问题,因为它将在我的 foreach 循环中?或者你是说 Task.WaitAll 应该有它自己的 try/catch 块?
  • 啊,我刚刚浏览了你的代码并错过了循环。

标签: c# task aggregateexception


【解决方案1】:

如果任务内部发生异常,则当您为任务Wait 时,调用线程会引发异常。如果成功创建了任务,则任务内发生的所有异常都将包装在 AggregateException 中并在等待时抛出。

例如,这意味着您可以删除循环中的 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
}

【讨论】:

  • 我有一个问题...如果您将 WaitAll 放入 try-catch 块中,并且您有 5 个任务。五个之一引发异常。它会弹出,而不是等待其他 4 个(好)任务吗?将 WaitAll 放在 trycatch 块中是否还有其他注意事项
猜你喜欢
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
相关资源
最近更新 更多