4.8 处理任务中的异常

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

     class Program
    {
        static void Main(string[] args)
        {
            //声明一个任务
            Task<int> task;
            //第一种方式,普通的try...catch捕获异常
            try
            {
                task = Task.Run(() => TaskMethod("Task 1", ));
                int result = task.Result;
                Console.WriteLine("Result: {0}", result);
            }
            catch (Exception ex)
            {
                //这里捕获的异常是一个被封装的异常,叫做AggregateException
                Console.WriteLine("Exception caught: {0}", ex);
                Console.WriteLine("----------------------------------------------");
                //本例中AggregateException之中只有一个异常,因为只有一个任务抛出了异常
                Console.WriteLine("InnerException is {0}",ex.InnerException.ToString());
            }
            Console.WriteLine("----------------------------------------------");
            Console.WriteLine();             //第二种方式是采用GetAwaiter().GetResult()方法来访问任务结果,这种方式可以提取没有封装的异常
            try
            {
                task = Task.Run(() => TaskMethod("Task 2", ));
                int result = task.GetAwaiter().GetResult();
                Console.WriteLine("Result: {0}", result);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception caught: {0}", ex);
            }
            Console.WriteLine("----------------------------------------------");
            Console.WriteLine();             //第三个demo展示了两个任务抛出异常的情形。
            var t1 = new Task<int>(() => TaskMethod("Task 3", ));
            var t2 = new Task<int>(() => TaskMethod("Task 4", ));
            var complexTask = Task.WhenAll(t1, t2);
            var exceptionHandler = complexTask.ContinueWith(t =>
                    Console.WriteLine("Exception caught: {0}", t.Exception),
                    TaskContinuationOptions.OnlyOnFaulted
                );
            t1.Start();
            t2.Start();             Thread.Sleep(TimeSpan.FromSeconds());
        }         static int TaskMethod(string name, int seconds)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            //抛出一个异常
            throw new Exception("Boom!");
            return * seconds;
        }
   }

结果如下

第一个demo

第二个demo

第三个demo

4.9 并行运行任务
这个小节主要讲述了Task.WhenAll()和Task.WhenAny()这两个方法,一个是等待所有任务全执行后的操作,一个是等待任何一个任务执行完的操作。
例子:
class Program
    {
        static void Main(string[] args)
        {
            //创建两个任务firstTask和secondTask
            var firstTask = new Task<int>(() => TaskMethod("First Task", ));
            var secondTask = new Task<int>(() => TaskMethod("Second Task", ));
            //借助Task.WhenAll()方法创建第三个任务,该任务会在前两个任务完成后完成
            var whenAllTask = Task.WhenAll(firstTask, secondTask);
          //whenAllTask任务结束以后会产生一个结果数组,
          //对应的第一个元素是第一个任务结果,第二个元素对应的是第二个任务结果...
          whenAllTask.ContinueWith(t =>
                Console.WriteLine("The first answer is {0}, the second is {1}", t.Result[], t.Result[]),
                TaskContinuationOptions.OnlyOnRanToCompletion
                );            firstTask.Start();
           secondTask.Start();            Thread.Sleep(TimeSpan.FromSeconds());             //这个demo,展示了启动一系列任务运行的过程
            var tasks = new List<Task<int>>();
            for (int i = ; i < ; i++)
            {
                int counter = i;
                var task = new Task<int>(() => TaskMethod(string.Format("Task {0}", counter), counter));
                tasks.Add(task);
                task.Start();
            }             while (tasks.Count > )
            {
                //使用Task.WhenAny()方法等待任务当中的任何一个任务完成
                var completedTask = Task.WhenAny(tasks).Result;
                //每当一个任务完成,就把他从任务列表移除,直到任务列表为空
                tasks.Remove(completedTask);
                Console.WriteLine("A task has been completed with result {0}.", completedTask.Result);
            }             Thread.Sleep(TimeSpan.FromSeconds());
        }         static int TaskMethod(string name, int seconds)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            return * seconds
}

C#当中的多线程_任务并行库(下)的更多相关文章

  1. C#当中的多线程_任务并行库(上)

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  2. C#当中的多线程_任务并行库(中)

    发现自己有点懒了!也可能是越往后越难了,看书理解起来有点费劲,所以这两天就每天更新一点学习笔记吧. 4.5 将APM模式转化为任务 书上提供的三种方式 方式一: class Program       ...

  3. C#多线程开发-任务并行库04

    你好,我是阿辉. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑, ...

  4. C#当中的多线程_线程池

    3.1 简介 线程池主要用在需要大量短暂的开销大的资源的情形.我们预先分配一些资源在线程池当中,当我们需要使用的时候,直接从池中取出,代替了重新创建,不用时候就送回到池当中. .NET当中的线程池是受 ...

  5. C#当中的多线程_线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

  6. C#当中的多线程_线程基础

    前言 最近工作不是很忙,想把买了很久了的<C#多线程编程实战>看完,所以索性把每一章的重点记录一下,方便以后回忆. 第1章 线程基础 1.创建一个线程 using System; usin ...

  7. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  8. C#多线程编程系列(五)- 使用任务并行库

    目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...

  9. C#并行库(TaskParallelLibrary)用法小结

    今天有空,总结一下.NET 4.5并行库(TaskParallelLibrary)用法. 也许C和C++的程序员刚刚开始写C#还习惯于new Thread来新建一个线程,但新建线程需要内存和CPU上下 ...

随机推荐

  1. bzoj1858

    比较烦的线段树 首先询问3很弱智不说, 询问4以前做过类似的,好像是USACO月赛hotel那题类似,维护lmax,rmax,max三个域就可以了 操作0,操作1也很简单,仔细考虑一下就知道也是可以l ...

  2. js怎样生成json的数据

    var row1 = {};row1.name = 'david';row1.age = '20'; //或者var row2 = {name: 'peter', age: '23'}; var da ...

  3. 最近买了个Mac Pro,用起来感觉是去年买了个表

    最近买了个 Mac Pro ,用了两个星期,强烈建议大家不要买 Mac Pro (128G)搞开发,反而建议用同样的价格,我买的是最便宜8千的,去买个带固态硬盘的联想X系列绝对比Pro好. 一.操作方 ...

  4. javascrip中array使用(续)

    ECMAScript 5中的数组的方法 Ecmascript5定义了9个新的数组方法遍历,映射,过滤,检测,简化和搜索数组. 1.forEach() Array.orEach()方法从头到尾遍历数组, ...

  5. 小Q书桌的下载、安装和使用

    最近,无意之间,在某大牛电脑里,使用到了这款软件.感谢! 确实,挺实用和方便的,强烈推荐!!! 1.  下载 http://qdesk.qq.com/ 2.  安装 3.  使用 多么方便啊!

  6. 普通Windows控制台窗口运行nmake编译VC

    我的GDAL编译都是在VS2012提供的prompt windows里面运行nmake完成的.但是如果想将编译自动化,放到Jenkins里面怎么办呢?首先没有VS2012的工程,也不想费力去生成一个, ...

  7. Code Forces Gym 100886J Sockets(二分)

    J - Sockets Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Valera ...

  8. JAVA基础英语单词表(上)

    action                            / 'ækʃən /          动作,行为 active                           / 'ækti ...

  9. MISCONF Redis is configured to save RDB snapshots

    今天客户突然反馈用我们的api出现了下面的这个错误 MISCONF Redis is configured to save RDB snapshots, but is currently not ab ...

  10. HighCharts基本使用实例(入门)

    HighCharts 摘要 HighCharts是眼下最为流行的图表插件,应用范围广泛,眼下支持曲线图.区域图.3D图.柱状图.饼图.散列图.混合图等,而且还支持一些拓展的特殊图表,如:仪表图.极地图 ...