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. POJ_1065_Wooden_Sticks_(动态规划,LIS+鸽笼原理)

    描述 http://poj.org/problem?id=1065 木棍有重量 w 和长度 l 两种属性,要使 l 和 w 同时单调不降,否则切割机器就要停一次,问最少停多少次(开始时停一次). Wo ...

  2. BZOJ_1015_星球大战_[JSOI2008]_(并查集)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1015 n 个点,被 m 条边相连.进行k次删点操作,问第一次操作前和每次操作后的集合数(直接或 ...

  3. 基于开源软件在Azure平台建立大规模系统的最佳实践

    作者 王枫 发布于2014年5月28日 前言 Microsoft Azure 是微软公有云的唯一解决方案.借助这一平台,用户可以以多种方式部署和发布自己的应用. 这是一个开放的平台,除了对于Windo ...

  4. 面向中国 Azure 开发者发布开源解决方案指南

     发布于 2014-05-23 作者 刘 天栋 Azure 是一个开放.灵活的云平台,可支持大量且不断增长的开源应用程序.框架和语言.微软及微软开放技术通过与全球及中国本地的开源社区不懈地合作,将 ...

  5. 【Android 复习】:从Activity中返回数据

    在实际的应用中,我们不仅仅要向Activity传递数据,而且要从Activity中返回数据,虽然返回数据和传递类似,也可以采用上一讲中的四种方式来传递数据,但是一般建议采用Intent对象的方式的来返 ...

  6. Sql Server CONVERT获取当前日期及日期样式

    Sql Server CONVERT获取当前日期及日期样式(转)(2012-06-06 12:00:24) 转载▼ // 标签: 杂谈 分类: SQL Sql Server CONVERT样式 获取当 ...

  7. Razor 语法快速参考

    Razor 语法快速参考   本文引自:http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx 语法名称 Raz ...

  8. git 命令归纳

    git 新手一枚,随用随更新 git clone git@example.com:project-name.git 克隆 git branch [-a -r] 查看分支[所有 远端] git pull ...

  9. CentOS Nginx+jdk+tomcat 环境搭建

    一.jdk安装 jdk下载地址:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloa ...

  10. John(博弈)

    Description Little John is playing very funny game with his  younger brother. There  is one big box ...