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. Flash加载网页内容

    import flash.net.URLLoader; var m_loader:URLLoader = new URLLoader(); m_loader.addEventListener(Even ...

  2. 奇怪的Lisp和难懂的计算机程序的构造和解释

    最近用新买的 Kindle 看<黑客与画家>的Lisp部分,发现作者 Paul Graham 很推崇 Lisp 语言,并且认为其它语言都没有Lisp简洁“成熟”,并且举例证明其它语言都在往 ...

  3. BWT(Burrows-Wheeler Transformation)的讲解及java实现

    BWT(Burrows-Wheeler Transformation) 1.什么是BWT 压缩技术主要的工作方式就是找到重复的模式,进行紧密的编码. BWT(Burrows–Wheeler_trans ...

  4. 【转】【阮一峰的网络日志】Git 使用规范流程

    作者: 阮一峰 日期: 2015年8月 5日 团队开发中,遵循一个合理.清晰的Git使用流程,是非常重要的. 否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护. 下面是Th ...

  5. Clean Code读书笔记

    第一章 整洁代码 1.编程要做什么 代码呈现了需求的细节,在某些层面上,这些细节无法被忽略或抽象,必须明确.而将需求明确到机器可以执行的细节程度,就是编程要做的事. 2.项目过程中经常遇到这样的问题: ...

  6. 【python自动化第二篇:python入门】

    内容概览 模块 python运行过程 基本数据类型(数字,字符串) 序列类型(列表,元组,字典) 模块使用 模块我们可以把它想象成导入到python以增强其功能的一种拓展.需要使用import来导入模 ...

  7. 阅读《effective java-第17条》遇到的问题解决与分享

    问题背景 最近这2天准备重新看一遍<effective java>,发现这些经典的书籍真的是看一遍又有一遍的感受.也越来越觉的学习的过程是一个重复的过程.这次遇到的问题是在第17条中看到的 ...

  8. C++:复制构造函数在什么时候被调用?

    这个问题不是疑问了,查了一下国外网站,总结一下.假设Person是一个类,复制构造函数的调用会在以下几种情况下发生: 1.对象在创建时使用其他的对象初始化 Person p(q); //此时复制构造函 ...

  9. 在JSP页面中调用另一个JSP页面中的变量

    在jsp学习中,经常需要在一个jsp页面中调用另一个jsp页面中的变量,下面就这几天的学习,总结一下. jsp页面之间的变量调用有多种方法: 1.通过jsp的内置对象—request对象获取参数: ( ...

  10. word模版另存为网页(*.htm,*.html),转为jsp页面并加入数据后导出成word

    word模版另存为网页之后,将html格式的文件转为jsp页面,在页面上加入相应的动态值,加入的值中包含图片,这个该怎么处理??另外导出的文件需要拷贝到不同的地方(无法联网)使用. <%@ pa ...