代码之家  ›  专栏  ›  技术社区  ›  neildt

task.waitall上的system.aggregateexception

  •  0
  • neildt  · 技术社区  · 5 年前

    我有下面的代码,它正在触发一些异步任务。

            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>
    

    只是一个简单的例子,我需要一个try-catch-around-task.waitall,或者我的代码应该有不同的结构。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Pretasoc    5 年前

    如果任务内部发生异常,则在调用线程上引发异常 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
    }