Using Tasks with conditional continuations

前端 未结 3 1154
一整个雨季
一整个雨季 2020-12-29 21:54

I\'m a little confused about how to use Tasks with conditional Continuations.

If I have a task, and then I want to continue with a tasks that handle success and erro

相关标签:
3条回答
  • 2020-12-29 22:20

    Isn't that normal?

    Looking at the MSDN documentation you're doing it fine and the logic you're implementing is sound. The only thing you're missing is wrapping the WaitAll call in an AggregateException wrapper like so:

    // Exceptions thrown by tasks will be propagated to the main thread
    // while it waits for the tasks. The actual exceptions will be wrapped in AggregateException.
    try
    {
        // Wait for all the tasks to finish.
        Task.WaitAll(tasks);
    
        // We should never get to this point
        Console.WriteLine("WaitAll() has not thrown exceptions. THIS WAS NOT EXPECTED.");
    }
    catch (AggregateException e)
    {
        Console.WriteLine("\nThe following exceptions have been thrown by WaitAll(): (THIS WAS EXPECTED)");
        for (int j = 0; j < e.InnerExceptions.Count; j++)
        {
            Console.WriteLine("\n-------------------------------------------------\n{0}", e.InnerExceptions[j].ToString());
        }
    }
    

    You can read more here: http://msdn.microsoft.com/en-us/library/dd270695.aspx

    In essence catching an AggregatedException gets you the same thing as completing WaitAll. It's a collection of all the exceptions returned from your tasks.

    0 讨论(0)
  • 2020-12-29 22:34

    Use Task.WaitAny(onSuccess, onError);

    0 讨论(0)
  • 2020-12-29 22:38

    I think your main problem is that you're telling those two tasks to "Wait" with your call to

    Task.WaitAll(onSuccess, onError);
    

    The onSuccess and onError continuations are automatically setup for you and will be executed after their antecedent task completes.

    If you simply replace your Task.WaitAll(...) with taskThrows.Start(); I believe you will get the desired output.

    Here is a bit of an example I put together:

    class Program
    {
        static int DivideBy(int divisor) 
        { 
          Thread.Sleep(2000);
          return 10 / divisor; 
        }
    
        static void Main(string[] args)
        {
            const int value = 0;
    
            var exceptionTask = new Task<int>(() => DivideBy(value));
    
            exceptionTask.ContinueWith(result => Console.WriteLine("Faulted ..."), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
            exceptionTask.ContinueWith(result => Console.WriteLine("Success ..."), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
    
            exceptionTask.Start();
    
            try
            {
                exceptionTask.Wait();
            }
            catch (AggregateException ex)
            {
                Console.WriteLine("Exception: {0}", ex.InnerException.Message);
            }
    
            Console.WriteLine("Press <Enter> to continue ...");
            Console.ReadLine();
        }
    }
    
    0 讨论(0)
提交回复
热议问题