.NET 并行(多核)编程系列之六 Task基础部分完结篇

.NET 并行(多核)编程系列之六 Task基础部分完结篇

  前言:之前的文章介绍了了并行编程的一些基本的,也注重的讲述了Task的一些使用方法,本篇很短,将会结束Task的基础知识的介绍。

 

  本篇的主要议题如下:

  1.       获取Task的状态

  2.       执行晚加载的Task(Lazily Task)

  3.       常见问题的解决方案

 

  系列文章链接:

  .NET 4 并行(多核)编程系列之一入门介绍

  .NET 4 并行(多核)编程系列之二 从Task开始 

  .NET 4 并行(多核)编程系列之三 从Task的取消 

  .NET 4 并行(多核)编程系列之四 Task的休眠 

  .NET 并行(多核)编程系列之五 Task执行和异常处理 

  .NET 并行(多核)编程系列之六 Task基础部分完结篇 

  .NET 并行(多核)编程系列之七 共享数据问题和解决概述

 

  1.       获取Task的状态

        在.NET并行编程还有一个已经标准化的操作就是可以获取task的状态,通过Task.Status属性来得到的,这个属性返回一个System.Threading.Tasks.TaskStatus的枚举值。

如下:

       Created:表明task已经被初始化了,但是还没有加入到Scheduler中。

       WatingForActivationtask正在等待被加入到Scheduler中。

 WaitingToRun:已经被加入到了Scheduler,等待执行。

       Runningtask正在运行

       WaitingForChildrenToComplete:表明父task正在等待子task运行结束。

       RanToCompletion:表明task已经执行完了,但是还没有被cancel,而且也这个task也没有抛出异常。

       Canceled:表明task已经被cancel了。(大家可以参看之前讲述取消task的文章)

       Faulted:表明task在运行的时候已经抛出了异常。

 

  2.       执行晚加载的Task(Lazily Task)

晚加载,或者又名延迟初始化,主要的好处就是避免不必要的系统开销。在并行编程中,可以联合使用Lazy变量和Task<>.Factory.StartNew()做到这点。(Lazy变量时.NET 4中的一个新特性,这里大家不用知道Lazy的具体细节)

       Lazy变量只有在用到的时候才会被初始化。所以我们可以把Lazy变量和task的创建结合:只有这个task要被执行的时候才去初始化。

       下面还是通过例子来讲解: 

 

ExpandedBlockStart.gif代码
  static void Main(string[] args)
        {
            
// define the function
            Func<string> taskBody = new Func<string>(() =>
            {
                Console.WriteLine(
"Task body working...");
                
return "Task Result";
            });

            
// create the lazy variable
            Lazy<Task<string>> lazyData = new Lazy<Task<string>>(() =>
            Task
<string>.Factory.StartNew(taskBody));

            Console.WriteLine(
"Calling lazy variable");
            Console.WriteLine(
"Result from task: {0}", lazyData.Value.Result);

            
// do the same thing in a single statement
            Lazy<Task<string>> lazyData2 = new Lazy<Task<string>>(
            () 
=> Task<string>.Factory.StartNew(() =>
            {
                Console.WriteLine(
"Task body working...");
                
return "Task Result";
            }));

            Console.WriteLine(
"Calling second lazy variable");
            Console.WriteLine(
"Result from task: {0}", lazyData2.Value.Result);

            
// wait for input before exiting
            Console.WriteLine("Main method complete. Press enter to finish.");
            Console.ReadLine();
        }

 

      

  首先我们回想一下,在之前的系列文章中我们是怎么定义一个task的:直接new,或者通过taskfactory来创建,因为创建task的代码是在main函数中的,所以只要new了一个task,那么这个task就被初始化。现在如果用了Lazytask,那么现在我们初始化的就是那个Lazy变量了,而没有初始化task(初始化Lazy变量的开销小于初始化task),只有当调用了lazyData.Value时,Lazy变量中包含的那个task才会初始化。(这里欢迎大家提出自己的理解) 

 

  3.       常见问题的解决方案

a.       Task 死锁

描述:如果有两个或者多个task(简称TaskA)等待其他的taskTaskB)执行完成才开始执行,但是TaskB也在等待TaskA执行完成才开始执行,这样死锁就产生了。

 

解决方案:避免这个问题最好的方法就是:不要使的task来依赖其他的task。也就是说,最好不要你定义的task的执行体内包含其他的task

 

例子:在下面的例子中,有两个task,他们相互依赖:他们都要使用对方的执行结果。当主程序开始运行之后,两个task也开始运行,但是因为两个task已经死锁了,所以主程序就一直等待。

 

 

ExpandedBlockStart.gif代码
  static void Main(string[] args)
        {
            
// define an array to hold the Tasks
            Task<int>[] tasks = new Task<int>[2];

            
// create and start the first task
            tasks[0= Task.Factory.StartNew(() =>
            {
                
// get the result of the other task,
                
// add 100 to it and return it as the result
                return tasks[1].Result + 100;
            });

            
// create and start the second task
            tasks[1= Task.Factory.StartNew(() =>
            {
                
// get the result of the other task,
                
// add 100 to it and return it as the result
                return tasks[1].Result + 100;
            });


            
// wait for the tasks to complete
            Task.WaitAll(tasks);

            
// wait for input before exiting
            Console.WriteLine("Main method complete. Press enter to finish.");
            Console.ReadLine();
        }

 

 

   本篇就到这里了,很短,基础的部分就基本介绍完了,后面的文章就开始讲述应用。

   版权为小洋和博客园所有,转载请标明出处给作者。

   http://www.cnblogs.com/yanyangtian

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/268204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sring AOP(简记)

什么是AOP AOP&#xff08;Aspect-OrientedProgramming&#xff0c;面向方面编程&#xff09;&#xff0c;可以说是OOP&#xff08;Object-Oriented Programing&#xff0c;面向对象编程&#xff09;的补充和完善。OOP允许你定义从上到下的关系&#xff0c;但并不适合定义从左到…

docker 什么是虚悬镜像

什么是虚悬镜像 仓库名、标签都是 none的镜像就是虚悬镜像(dangling image) 这种镜像需要删除&#xff0c;根据镜像ID删除该虚悬镜像 docker rmi -f [IMAGE ID]

2010年06月12日

为什么80%的码农都做不了架构师&#xff1f;>>> 今天装了个rhel 5.5,想制定光盘做yum源&#xff0c;网上找了个资料&#xff1a; rhel 5.x 将YUM指定为光盘--yum配置格式示例 后经过自己测试发现&#xff0c;只需要&#xff1a; 1. mount -o loop rhel-5-server-dv…

2017.10.25

日期计算 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;1描述如题&#xff0c;输入一个日期&#xff0c;格式如&#xff1a;2010 10 24 &#xff0c;判断这一天是这一年中的第几天。输入第一行输入一个数N&#xff08;0<N<100&#xff…

如何现实CITRIX XenAPP内容重定向

在使用CITRIX XenAPP为用户交付各大应用时&#xff0c;我们会让到一个问题&#xff0c;比如说&#xff0c;我采用XENAPP交付给用户了MS-OFFICE WORD应用&#xff0c;而此用户在他本机并未安装任何的OFFICE 版本&#xff0c;那么&#xff0c;当用户在打开*.doc/*.docx文件时&…

JAVA-初步认识-第八章-继承-单继承和多重继承

一. 说完了继承的基本概述之后&#xff0c;了解一下在java中它的体现方式。 大家都知道java来自于c&#xff0c;c有多继承&#xff0c;java对其中的多继承进行了改良。为什么不直接支持多继承呢&#xff1f;要牢记&#xff0c;这个原因在后面可以解决很多问题。 二. 观看下面的…

docker重启容器

docker restart 容器id

让你的Silverlight程序部署在任意服务器上

今天在CSDN上逛&#xff0c;看到一篇不错的教程贴&#xff0c;“让你的SilverLight程序部署在任意服务器上”&#xff0c;转到园子里&#xff0c;希望更多朋友受益。 即使是免费的只支持HTML的空间&#xff0c;同样可以部署SilverLight应用。众所周知&#xff0c;SilverLight的…

VS2010小Bug:找不到System.Web.Extensions.dll引用

用上VS 2010的日子&#xff0c;快乐并痛着... 今天本来是想写这篇随笔的&#xff0c;却在处理朝阳无限提交的新模板的CSS时&#xff0c;一打开CSS文件&#xff0c;VS2010就崩溃&#xff0c;于是发现了VS2010的另一个Bug。 这个VS2010的Bug是在将博客园博问的代码从VS2008升级至…

TCP 之 RST 原因分析

5. 往一个对端已经关闭的套接字上写入数据会收到一个RST信号 1.发送端的 发送缓冲区还有数据&#xff0c;但接收端tcp的接收通道已关闭 2. SYN到达某端口但此端口上没有正在监听的服务器。对于UDP,当一个数据报到达目的端口时,该端口没在使用,它将产生一个ICMP端口不可达的信息…

《Windows核心编程》---剪贴板

剪贴板是由系统定义的&#xff0c;并不属于任何一个特定的进程。系统中所有进程都可以访问和设置剪贴板。剪贴板最大的特点就是数据传输没有明确的目标&#xff0c;数据是被动访问的&#xff1b;剪贴板的内容可以被多次访问&#xff0c;直到新的数据写入。剪贴板是一种可供选择…

docker后台守护式启动

docker后台启动 docker run -d 镜像名

浏览器打不开网页,但是还可以聊qq?

电脑网络明明已经连接&#xff0c;但是就是打不开网页&#xff1f;下面介绍下解决方法。 原因&#xff1a;DNS解析导致网页打不开。路由器没有获取到DNS 我们的系统会缓存我们平时用到的一些DNS地址&#xff0c;这个功能主要是加速我们对网络的访问。但是有时候这些缓存的DNS地…

项目重构方案设计

最近接手到一个已经成型的项目&#xff0c;然后我们的任务就是对它进行重构&#xff0c;这个项目是一个功能很齐全的WPF视频播放器&#xff08;附带很多其他功能&#xff09;&#xff0c;在仔细 研究了项目的背景和架构以后&#xff0c;初步做出了一下的重构方案&#xff1a; 目…

docker top查看容器中运行的进程信息

docker top :查看容器中运行的进程信息&#xff0c;支持 ps 命令参数。 语法 docker top [OPTIONS] CONTAINER [ps OPTIONS] 容器运行时不一定有/bin/bash终端来交互执行top命令&#xff0c;而且容器还不一定有top命令&#xff0c;可以使用docker top来实现查看container中正…

易经给我们的64个人生智慧

《易经》没有那么神秘&#xff0c;它是科学的&#xff0c;它就在我们的身边&#xff0c;我们每天的生活起居&#xff0c;工作事业&#xff0c;健康幸福&#xff0c;都受这64个哲理的左右。我们以科学的态度对待这64个哲理&#xff0c;就形成了64个感悟&#xff0c;64个感悟回答…

华为2018软件岗笔试题解题思路和源代码分享

2017年9月26日&#xff0c;参加了华为技术有限公司的笔试&#xff0c;题目类型是软件题&#xff0c;没有选择填空问答类型&#xff0c;总共是3道编程题目&#xff0c;题目难度适中&#xff0c;在两个小时内完成3道题目的AC&#xff0c;所以分享的代码都是可运行且完全AC的! 和广…

docker镜像加载原理

docker镜像加载原理