简体   繁体   English

C#Task.WaitAll()使用错误处理取消

[英]C# Task.WaitAll() Cancelation with Error handling

I have a problem. 我有个问题。 I try to run multiple long running tasks. 我尝试运行多个长时间运行的任务。 If one fails I wanna cancel all other tasks and get the failure exception. 如果一个失败,我想取消所有其他任务并获得失败异常。 The example given below. 下面给出的例子。 I wanna catch AggregateException with Exception thrown by 我想捕获抛出异常的AggregateException

 throw new Exception("FailureTask");

But instead of AggregateException I am catching OperationCanceledException, because I wanna cancel all other task. 但是我没有使用AggregateException来捕获OperationCanceledException,因为我想取消所有其他任务。

    [TestMethod]
    public void TestParallelTaskCancelation()
    {
        var cancellationTokenSource = new CancellationTokenSource();
        Task[] tasks =
        {
            Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
            Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
            Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
            Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
            Task.Factory.StartNew(FailureTask, cancellationTokenSource, cancellationTokenSource.Token)
        };

        try
        {
            Task.WaitAll(tasks, cancellationTokenSource.Token);
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine(e.GetaAllMessages());
        }
        catch (AggregateException e)
        {
            Console.WriteLine(e.GetaAllMessages());
        }
    }

    private void DummyTask(object o)
    {
        var cancellationToken = (CancellationTokenSource)o;
        while (true)
        {
            Thread.Sleep(10000);
            if (cancellationToken.IsCancellationRequested)
            {
                cancellationToken.Token.ThrowIfCancellationRequested();
            }
        }
    }

    private void FailureTask(object o)
    {
        var cancellationToken = (CancellationTokenSource)o;

        var executionTask = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            throw new Exception("FailureTask");
        }, cancellationToken.Token);

        executionTask.ContinueWith(t =>
        {
            cancellationToken.Cancel(false);
            throw new Exception(t.Exception.GetaAllMessages());
        }, TaskContinuationOptions.OnlyOnFaulted);

        if (executionTask.Wait(10 * 1000, cancellationToken.Token)) return;
        //timeout !!!
        throw new Exception("The limit 'Max Seconds Per Query' has been exceeded!!!");
    }`

Please help. 请帮忙。

This works for me 这适合我

public static async void TestParallelTaskCancelation()
    {
        var cancellationTokenSource = new CancellationTokenSource();
        Task[] tasks =
        {
        Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
        Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
        Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
        Task.Factory.StartNew(DummyTask, cancellationTokenSource, cancellationTokenSource.Token),
        Task.Factory.StartNew(FailureTask, cancellationTokenSource, cancellationTokenSource.Token)
        };

        try
        {
           await Task.WhenAll(tasks);
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine(e.ToString());
        }
        catch (AggregateException e)
        {
            Console.WriteLine(e.ToString());
        }
    }

您应该使用throw AggregateException构造函数而不仅仅是Exception

throw new AggregateException ("FailureTask");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM