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. jBPM 4.4 数据库设计

    1         存储流程定义相关的部署信息数据库 1.1              jbpm4_deployment 字段名 字段含义 类型 允许空值 键 DBID_ 流程模板标识 Bigint( ...

  2. 【转】命令行使用7zip

    原文网址:http://blog.csdn.net/Gildor/article/details/3358127 现在大家都用WinRAR,不知道听说过7zip的朋友多不多.7zip是一个开源的压缩软 ...

  3. 【Android 复习】:Android之ViewFlipper(一)

    屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面. 通过查看Android API文档可以发现, ...

  4. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  5. Bzoj 3343: 教主的魔法 分块,二分

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 364[Submit][Status][Discuss ...

  6. 安卓开发无法识别手机原因之一:手机SDK比工程要求的最小SDK低

      创建工程时,设置限制的最小SDK:   如果你手机的内核版本比你工程的设置的最小SDK低,则不显示   来自为知笔记(Wiz)

  7. Nginx具体的压缩配置

    以下是自学it网--中级班上课笔记 网址:www.zixue.it 常用以下配置 gzip on|off gzip_buffers 4K|8K 缓冲(和硬盘块相当) gzip_comp_level [ ...

  8. linux内核--内核内存管理

    如题目所示,为什么要称作“内核内存管理”,因为内核所需要的内存和用户态所需要的内存,这两者在管理上是不一样的. 这篇文章描述内核的内存管理,用户态的内存管理在以后的文章中讲述. 首先简单的说明一下下面 ...

  9. [Spark] Pair RDD常见转化操作

    本篇博客中的操作都在 ./bin/pyspark 中执行. 对单个 Pair RDD 的转化操作 下面会对 Pair RDD 的一些转化操作进行解释.先假设我们有下面这些RDD(在pyspark中操作 ...

  10. 学习:Linux基础知识<一>

    >>硬盘分区模式 硬盘分区模式一般如下: -- /  (根目录) -- /usr    (操作系统) --/home (用户信息) -- /var    (默认服务器的登录文件,邮件与WW ...