zoukankan      html  css  js  c++  java
  • C#当中的多线程_任务并行库(下)

    4.8 处理任务中的异常

    下面这个例子讨论了任务当中抛出异常,以及任务异常的获取

    1     class Program
    2     {
    3         static void Main(string[] args)
    4         {
    5             //声明一个任务
    6             Task<int> task;
    7             //第一种方式,普通的try...catch捕获异常
    8             try
    9             {
    10                 task = Task.Run(() => TaskMethod("Task 1", 2));
    11                 int result = task.Result;
    12                 Console.WriteLine("Result: {0}", result);
    13             }
    14             catch (Exception ex)
    15             {
    16                 //这里捕获的异常是一个被封装的异常,叫做AggregateException
    17                 Console.WriteLine("Exception caught: {0}", ex);
    18                 Console.WriteLine("----------------------------------------------");
    19                 //本例中AggregateException之中只有一个异常,因为只有一个任务抛出了异常
    20                 Console.WriteLine("InnerException is {0}",ex.InnerException.ToString());
    21             }
    22             Console.WriteLine("----------------------------------------------");
    23             Console.WriteLine();
    24 
    25             //第二种方式是采用GetAwaiter().GetResult()方法来访问任务结果,这种方式可以提取没有封装的异常
    26             try
    27             {
    28                 task = Task.Run(() => TaskMethod("Task 2", 2));
    29                 int result = task.GetAwaiter().GetResult();
    30                 Console.WriteLine("Result: {0}", result);
    31             }
    32             catch (Exception ex)
    33             {
    34                 Console.WriteLine("Exception caught: {0}", ex);
    35             }
    36             Console.WriteLine("----------------------------------------------");
    37             Console.WriteLine();
    38 
    39 
    40             //第三个demo展示了两个任务抛出异常的情形。
    41             var t1 = new Task<int>(() => TaskMethod("Task 3", 3));
    42             var t2 = new Task<int>(() => TaskMethod("Task 4", 2));
    43             var complexTask = Task.WhenAll(t1, t2);
    44             var exceptionHandler = complexTask.ContinueWith(t => 
    45                     Console.WriteLine("Exception caught: {0}", t.Exception), 
    46                     TaskContinuationOptions.OnlyOnFaulted
    47                 );
    48             t1.Start();
    49             t2.Start();
    50 
    51             Thread.Sleep(TimeSpan.FromSeconds(5));
    52         }
    53 
    54         static int TaskMethod(string name, int seconds)
    55         {
    56             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    57                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    58             Thread.Sleep(TimeSpan.FromSeconds(seconds));
    59             //抛出一个异常
    60             throw new Exception("Boom!");
    61             return 42 * seconds;
    62         }
    63    }

    结果如下

    第一个demo

    第二个demo

     第三个demo

    4.9 并行运行任务
    这个小节主要讲述了Task.WhenAll()和Task.WhenAny()这两个方法,一个是等待所有任务全执行后的操作,一个是等待任何一个任务执行完的操作。
    例子:
    1 class Program
    2     {
    3         static void Main(string[] args)
    4         {
    5             //创建两个任务firstTask和secondTask
    6             var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
    7             var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));
    8             //借助Task.WhenAll()方法创建第三个任务,该任务会在前两个任务完成后完成
    9             var whenAllTask = Task.WhenAll(firstTask, secondTask);
    10           //whenAllTask任务结束以后会产生一个结果数组,
    11           //对应的第一个元素是第一个任务结果,第二个元素对应的是第二个任务结果...
    12           whenAllTask.ContinueWith(t =>
    13                 Console.WriteLine("The first answer is {0}, the second is {1}", t.Result[0], t.Result[1]),
    14                 TaskContinuationOptions.OnlyOnRanToCompletion
    15                 );
    16 
    17            firstTask.Start();
    18            secondTask.Start();
    19 
    20            Thread.Sleep(TimeSpan.FromSeconds(4));
    21 
    22             //这个demo,展示了启动一系列任务运行的过程
    23             var tasks = new List<Task<int>>();
    24             for (int i = 1; i < 4; i++)
    25             {
    26                 int counter = i;
    27                 var task = new Task<int>(() => TaskMethod(string.Format("Task {0}", counter), counter));
    28                 tasks.Add(task);
    29                 task.Start();
    30             }
    31 
    32             while (tasks.Count > 0)
    33             {
    34                 //使用Task.WhenAny()方法等待任务当中的任何一个任务完成
    35                 var completedTask = Task.WhenAny(tasks).Result;
    36                 //每当一个任务完成,就把他从任务列表移除,直到任务列表为空
    37                 tasks.Remove(completedTask);
    38                 Console.WriteLine("A task has been completed with result {0}.", completedTask.Result);
    39             }
    40 
    41             Thread.Sleep(TimeSpan.FromSeconds(1));
    42         }
    43 
    44         static int TaskMethod(string name, int seconds)
    45         {
    46             Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
    47                 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    48             Thread.Sleep(TimeSpan.FromSeconds(seconds));
    49             return 42 * seconds
    50         }

     

  • 相关阅读:
    协程—gevent模块的使用
    协程—概念以及基本使用
    Python—同步和互斥
    Hugo博客搭建
    Linux编辑利器-Vim
    Linux命令与Shell
    python入门基础
    .netcore程序在linux下用supervisor守护
    .netcore中添加Swagger
    winform或wpf中全局异常捕获
  • 原文地址:https://www.cnblogs.com/dcz2015/p/5066836.html
Copyright © 2011-2022 走看看