处理任务并行库

时间:2015-04-30 11:40:42

标签: c# .net multithreading exception task-parallel-library

我从COLIN Mackay博客上的这篇文章中得到了以下代码。 Tasks that throw exceptions正如本文所暗示的那样,任务中抛出的异常不会被冒泡,除非调用其中一个等待...方法(不包括WaitAny)。我有2个类似的场景,给出两个不同的结果。

第一个场景

  1. 注释掉(首先评论
  2. 下的部分
  3. 将部分保留在(评论第二次)未注释
  4. 使用 ctrl + f5 运行控制台应用程序,以便deubugger不会在异常中断。
    1. 观察即使任务抛出异常,除非调用wait方法,否则异常不会冒泡。(按两次enter键调用wait方法)
  5. First Scenario

    第二种情景

    1. 评论下的部分(评论第二次)
    2. 将部分保留在(注释第一个)未注释
    3. 使用 ctrl + f5 运行控制台应用程序,以便deubugger不会在异常中断。
      1. 现在异常也没有冒泡,但差异在于任务没有启动,因为控制台没有将任务的状态显示为第一个场景,即使两者都被抛出异常。 有人可以解释这种行为以及两种例外之间的差异。
    4. second scenario 这是代码。

      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);
              }
          }
      }
      

1 个答案:

答案 0 :(得分:3)

  

差异在于任务没有启动,因为控制台没有   将任务的状态显示为第一个场景

那是因为第二次,在Console.WriteLine方法调用之前抛出了异常:

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

对战:

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

如果您想体验相同的行为,请在方法开头写到控制台:

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);
}