【问题标题】:How to make exception be awared of before calling Task.WaitAll?如何在调用 Task.WaitAll 之前注意异常?
【发布时间】:2015-11-11 18:40:08
【问题描述】:

就我而言,我通过以下方式创建任务:

IList<Task> Tasks = new List<Task>();
Tasks.Add(Task.Run(async () => { await functionAsync();}));

我需要这些任务无限运行,以便不断处理一些传入数据。但是,如果发生一些致命错误/异常,我需要通过取消所有任务来结束程序。我整理了一个简单的例子来模拟我打算做什么,但它不起作用。我认为抛出异常时任务将被视为结束,并且 WaitAny 应该返回 AggregatedException,但它似乎并不是它的实际工作方式。那么,我怎样才能使它正确呢?

public static void Main(string[] args)
{
    Console.WriteLine(nameof(Main));
    for (int i = 1; i < 5; i++)
    {
        var i1 = i;
        _tasks.Add(Task.Run(async () => { await Tryme(i1); }));
    }

    try
    {
        Task.WaitAny(_tasks.ToArray());
    }
    catch (Exception e)
    {
        Console.WriteLine("Stop my program if any of the task in _tasks throw exception");
        Console.WriteLine(e);
    }
    Console.ReadLine();
}

private static async Task Tryme(int i)
{

    Console.WriteLine($"I'm {i}");
    if (i == 3)
    {
        Console.WriteLine($"{i} is throwing the exception");
        throw new Exception("fake one");
    }
    await Task.Delay(TimeSpan.MaxValue);
}

【问题讨论】:

    标签: c# .net async-await task-parallel-library


    【解决方案1】:

    您可以使用TPL Dataflow,而不是手动取消整个任务链,如果发生未处理的异常,它会为您停止整个块,或者如果需要,可以配置为在other modes 中运行:

    var actionBlock = new ActionBlock<int>(i => TryMe(i));
    
    foreach (var num in Enumerable.Range(0, 100))
    {
       actionBlock.Post(num);
    }
    
    try
    {
       await actionBlock.Completion();
    }
    catch (Exception e)
    {
        // Block finished prematurely, handle exception.
    }
    

    注意 Dataflow 会为您处理 parralisation,无需手动创建任务。

    【讨论】:

      【解决方案2】:

      this post 获得了一些线索。看起来 WaitAny 不会抛出任何异常。我得到了例外:

      int faultIndex = Task.WaitAny(_tasks.ToArray());
      if (_tasks[faultIndex].IsFaulted)
      {
           Console.WriteLine($"{faultIndex} end");
           throw _tasks[faultIndex].Exception;
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-12
        • 2014-05-15
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 2012-07-20
        • 1970-01-01
        • 2018-05-09
        相关资源
        最近更新 更多