C# 异步编程3 TPL Task 异步程序开发
.Net在Framework4.0中增加了任务并行库,对开发人员来说利用多核多线程CPU环境变得更加简单,TPL正符合我们本系列的技术需求。因TPL涉及内容较多,且本系列文章为异步程序开发,所以本文并未涉及TPL全部内容。后续会写一个TPL系列的Blog,各位朋友可以关注一下。
TASK
TPL的基础Task,Task是TPL并行编程的最小单元,即表示一个异步操作。利用Task进行异步编程非常简单:
static void Main(string[] args)
{
BaseTaskDemo();
//BaseTaskDemo2();//两者效果相同
Console.WriteLine(String.Format("Main 线程:{0}", Thread.CurrentThread.ManagedThreadId));
Console.ReadLine();
}
private static void BaseTaskDemo()
{
var task = new Task(() => {
Thread.Sleep();
Console.WriteLine(String.Format("Task 线程:{0}", Thread.CurrentThread.ManagedThreadId));
});
task.Start();
}
private static void BaseTaskDemo2()
{
var task = Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine(String.Format("Task 线程:{0}", Thread.CurrentThread.ManagedThreadId));
});
}
程序说明:
1、new Task(Action)创建一个异步任务,参数Action是异步任务要执行的委托对象
2、task.Start()启动异步任务的执行
3、Task.Run(Action)等效于1、2的组合
上面的示例程序实现了异步操作,但主线程无法获知异步任务完成与否。为获取Task的执行结果,上面的程序进行如下修改:
static void Main(string[] args)
{
var task = TaskForResult();
Console.WriteLine(String.Format("Main 线程:{0}", Thread.CurrentThread.ManagedThreadId));
task.Wait();
if (task.IsCompleted)
Console.WriteLine(String.Format("获取异步执行结果:{0}", task.Result));
Console.ReadLine();
}
private static Task<int> TaskForResult()
{
var task = Task.Run(()=> {
Thread.Sleep();
Console.WriteLine(string.Format("Task 线程:{0},Task执行完成。", Thread.CurrentThread.ManagedThreadId));
return ;
});
return task;
}
程序说明:
1、下面代码的原型为Task.Run(Func<int>),Run的参数不再是Action,因为在该任务中我们要返回一个int值,所以应该使用Run(Func<T>)这个重载。
var task = Task.Run(()=> {
Thread.Sleep(2000);
Console.WriteLine(string.Format("Task 线程:{0},Task执行完成。", Thread.CurrentThread.ManagedThreadId));
return 10;
});
2、主线程中调用task.Wait()时,主线程将一直等待异步任务完成或被取消。
3、task.IsCompleted属性用于判断异步任务是否完成
4、task.Result获取异步任务的执行结果(返回值)
上面的示例程序已经实现了主线程获取异步程序的状态及返回值,但如果异步程序非常耗时,则存在主线程需要临时取消耗时异步程序执行的功能。为了满足上述要求,程序可做如下调整:
static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
var task = TaskForResult2(tokenSource);
Console.WriteLine(String.Format("Main 线程:{0}", Thread.CurrentThread.ManagedThreadId));
Console.WriteLine(String.Format("Main 线程:{0},获取异步执行结果:{1}", Thread.CurrentThread.ManagedThreadId, task.Result));
Console.ReadLine();
}
private static Task<int> TaskForResult2(CancellationTokenSource tokenSource)
{
var task = Task.Run(() =>
{
Thread.Sleep();
if (!tokenSource.IsCancellationRequested)
{
Console.WriteLine(String.Format("Task 线程:{0},任务1执行完成。", Thread.CurrentThread.ManagedThreadId));
return ;
}
else
{
return -;
}
}, tokenSource.Token);
return task;
}
程序说明:
1、CancellationTokenSource提供任务取消消息,构造参数 5000 表示CancellationTokenSource在发出5s后超时并取消
2、在Task的委托内部 tokenSource.IsCancellationRequested 获取取消标记
3、task.Result会隐式调用Wait()方法
如果异步Task在执行过程中出现异常,则需要对发生的异常做出响应:
static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
var task = TaskForResult2(tokenSource);
Console.WriteLine(String.Format("Main 线程:{0}", Thread.CurrentThread.ManagedThreadId));
try
{
//task.Wait();
Console.WriteLine(String.Format("Main 线程:{0},获取异步执行结果:{1}", Thread.CurrentThread.ManagedThreadId, task.Result));
}
catch (AggregateException ex)
{ }
Console.ReadLine();
}
private static Task<int> TaskForResult2(CancellationTokenSource tokenSource)
{
var task = Task.Run(() =>
{
Thread.Sleep();
if (!tokenSource.IsCancellationRequested)
{
throw new Exception("抛出异常");
}
else
{
return -;
}
}, tokenSource.Token);
return task;
}
程序说明:
1、在Task中引发的异常需要在 task.Wait()或task.Result时捕获
写在后面:Task的功能远不止上述这些,如Task多任务串行、TaskFactory、Paralle等知识非常有趣和重要。如果你感兴趣的话,可以关注本人后续TPL的文章。
C# 异步编程3 TPL Task 异步程序开发的更多相关文章
- C# 异步编程1 APM模式异步程序开发
C#已有10多年历史,单从微软2年一版的更新进度来看活力异常旺盛,C#中的异步编程也经历了多个版本的演化,从今天起着手写一个系列博文,记录一下C#中的异步编程的发展历程.广告一下:喜欢我文章的朋友,请 ...
- 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文
你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...
- Linux网络编程:基于UDP的程序开发回顾篇
基于无连接的UDP程序设计 同样,在开发基于UDP的应用程序时,其主要流程如下: 对于面向无连接的UDP应用程序在开发过程中服务端和客户端的操作流程基本差不多.对比面向连接的TCP程序,服务端少了 ...
- Linux网络编程:基于TCP的程序开发回顾篇《转》
面向连接的TCP程序设计 基于TCP的程序开发分为服务器端和客户端两部分,常见的核心步骤和流程: 其实按照上面这个流程调用系统API确实可以完全实现应用层程序的开发,一点问题没有.可随着时间的推移,你 ...
- 深入理解JS异步编程五(脚本异步加载)
异步脚本加载 阻塞性脚本 JavaScript在浏览器中被解析和执行时具有阻塞的特性,也就是说,当JavaScript代码执行时,页面的解析.渲染以及其他资源的下载都要停下来等待脚本执行完毕 浏览器是 ...
- C# 异步编程2 EAP 异步程序开发
在前面一篇博文记录了C# APM异步编程的知识,今天再来分享一下EAP(基于事件的异步编程模式)异步编程的知识.后面会继续奉上TPL任务并行库的知识,喜欢的朋友请持续关注哦. EAP异步编程算是C#对 ...
- .Net Core WebAPI 基于Task的同步&异步编程快速入门
.Net Core WebAPI 基于Task的同步&异步编程快速入门 Task.Result async & await 总结 并行任务(Task)以及基于Task的异步编程(asy ...
- 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]
看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.asp ...
- Async 、 Await 的异步编程(.NET 4.5 新异步模型) [转自MSDN]
使用异步编程,可以避免性能瓶颈和增强应用程序的总体响应能力. 但是,编写异步应用程序的以前的技术可能比较复杂,使它们难以编写,调试和维护. Visual Studio 2012 引入了一个简化的方法, ...
随机推荐
- win10 + gluon + GPU
1. 下载教程 可以用浏览器下载zip格式并解压,在解压目录文件资源管理器的地址栏输入cmd进入命令行模式. 也可以 git pull https://github.com/mli/gluon-tut ...
- IDEA里五种目录类型简介(Mark Directory as)
通过File -> Settings-project Structure-Modules 或者右键Mark Directory as可以找到这五种类型. Sources 一般用于标注类似 sr ...
- C# TableLayoutPanel使用方法
一.利用TableLayoutPanel类展示表格,以10行5列为例 第1步:在前台创建一个panel,使TableLayoutPanel对象填充其内部. 第2步:创建TableLayoutPanel ...
- Python 解析har 文件将域名分类导出
前言 作为程序员平时主要是使用 shadowsocks 作为代理工具的.shadowsocks 有个很明显的优点儿就是可以设置白名单和黑名单.白名单是会走shadowsocks的自动代理模式. 遇到的 ...
- Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析
前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...
- win32编程简介
win32编程简介 复习Win32整理下知识. 为什么学习win32? 我们要编写windos程序.都离不开API. 也就是我们所说的win32程序. 所以学好win32是你能不能再windows下编 ...
- 内核知识第六讲,内核编写规范,以及获取GDT表
内核知识第六讲,内核编写规范,以及获取GDT表 一丶内核驱动编写规范 我们都知道,在ring3下,如果我们的程序出错了.那么就崩溃了.但是在ring0下,只要我们的程序崩溃了.那么直接就蓝屏了. 那么 ...
- git第九节---git命令实战
1. git 项目创建 mkdir git-command 2.git 配置 git config --list 配置用户名 邮箱 git config user.name 'XXX' --loca ...
- jquery中innerwidth,outerwidth,outerwidth和width的区别
在jQuery中,width()方法用于获得元素宽度: innerWidth()方法用于获得包括内边界(padding)的元素宽度, outerWidth()方法用于获得包括内边界(padding)和 ...
- ASP.NET Identity 二 (转载)
来源:http://www.cnblogs.com/r01cn/p/5180892.html#undefined 推荐看原文,这里转载是怕好文章消失了. 注:本文是[ASP.NET Identity系 ...