简体   繁体   中英

Handling Exceptions in Task Parallel library

I got the below code from this article on COLIN Mackay's Blog. Tasks that throw exceptions as this article suggest is that exceptions thrown in the task are not bubbled up Unless one of the of the Wait… methods (excluding WaitAny) is called. well I have 2 similar scenarios that give two different results.

First Scenario

  1. comment out the part under ( comment this first )
  2. leave the part under ( comment this second ) uncommented
  3. run the console application using ctrl+f5 so that the deubugger will not break on the exception.
    1. observe that even though the task throw an exception the exception is not bubbled unless the wait method is called.(Press enter twice to call the wait method)

第一种情景

Second Scenario

  1. comment out the part under (comment this second)
  2. leave the part under (comment this first) uncommented
  3. run the console application using ctrl+f5 so that the deubugger will not break on the exception.
    1. now exception is also not bubbled but the diffrence is that the tasks didnt start as the console doesn't display the status of the task as the first scenario even though both are thrown exceptions. can someone explain this behavior and the diffrence between both exceptions.

第二种情况 here is the code.

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Threading
{
    class Program
    {
        static void Main(string[] args)
        {
            // Start the tasks
            List<Task> tasks = new List<Task>();
            for (int i = 0; i < 20; i++)
            {
                Task t = Task.Factory.StartNew(PerformTask);
                tasks.Add(t);
            }

            Console.WriteLine("Press enter to display the task status.");
            Console.ReadLine();

            // Display the status of each task.
            // If it has thrown an exception will be "faulted"
            foreach (Task t in tasks)
                Console.WriteLine("Task {0} status: {1}", t.Id, t.Status);

            Console.WriteLine("Press enter to wait for all tasks.");
            Console.ReadLine();

            // This is where the AggregateException is finally thrown
            Task.WaitAll(tasks.ToArray());

            Console.ReadLine();
        }

        public static void PerformTask()
        {
            //comment this first
            //string input = null;
            //string output = input.ToUpper();
            Console.WriteLine("Starting Task {0}", Task.CurrentId);
            //comment this second
            throw new Exception("Throwing exception in task " + Task.CurrentId);
        }
    }
}

the diffrence is that the tasks didnt start as the console doesn't display the status of the task as the first scenario

That's because the second time, the exception is thrown before your Console.WriteLine method call:

string input = null;
string output = input.ToUpper(); // this will throw
Console.WriteLine("Starting Task {0}", Task.CurrentId);

Versus:

Console.WriteLine("Starting Task {0}", Task.CurrentId); // This will first be written
throw new Exception("Throwing exception in task " + Task.CurrentId);

If you want to experience the same behavior, write out to the console at the beginning of your method:

public static void PerformTask()
{
    Console.WriteLine("Starting Task {0}", Task.CurrentId);

    //string input = null;
    //string output = input.ToUpper();

    throw new Exception("Throwing exception in task " + Task.CurrentId);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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