【问题标题】:How to stop task in pararell foreach loop when exception occurs?发生异常时如何在并行foreach循环中停止任务?
【发布时间】:2017-05-25 08:35:14
【问题描述】:

我需要知道当异常发生时如何在pararell foreach 循环中停止任务?如果 Foo1() 抛出异常 DoSomeWork() 应该被取消。

物品类别

class Item
 {
     public async Task DoSomeWork()
            {
                try
                {
                     await Foo1();
                     await Foo2();
                }
                catch (Exception ex)
                {
                    Console.Writeline(ex.Message);
                }
             }


    private async Task Foo1()
    {   
        try
        {
        //
        // some functionality
        //
        }
        catch(Exception ex)
        {
            // If exception occurs, then how cancel Task DoSomeWork()
        }
    }

    private async Task Foo2()
    {   
        try
        {
        //
        // some functionality
        //
        }
        catch(Exception ex)
        {
            // If exception occurs, then how cancel Task DoSomeWork()
        }
    }
}

以及带有 Pararell.Foreach 循环的 ItemCollection 类

class ItemCollection
{
     public void StartAsync()
        {
            try
            {
                IList<Task> il = new List<Task>();
                Parallel.ForEach(ListOfItems, t => il.Add(t.DoSomeWork()));
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message); 
            }
        }
}

在本例中如何使用 CancellationToken 属性?

【问题讨论】:

  • 只是不要捕获异常,或者如果你想记录日志,之后再抛出它
  • 是否也要取消循环的所有其他迭代?
  • @svick 不,只有抛出异常的任务。

标签: c# task parallel.foreach cancellation cancellationtokensource


【解决方案1】:

这是来自 MSDN 的一个很好的例子:https://msdn.microsoft.com/de-de/library/ee256691(v=vs.110).aspx

循环开始之前:

CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;

循环内部:

Parallel.ForEach(nums, po, (num) =>
                {
                    // Do some work here
                    po.CancellationToken.ThrowIfCancellationRequested();
                });

从另一个线程,可以触发取消事件:

cts.Cancel();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多