C#使用任务并行库(TPL)
TPL(Task Parallel Library)
任务并行库 (TPL) 是 System.Threading和 System.Threading.Tasks 命名空间中的一组公共类型和 API。 TPL 的目的是通过简化将并行和并发添加到应用程序的过程来提高开发人员的工作效率。
使用线程池可以减少并行操作时操作系统资源的开销,然而使用线程池并不简单,从线程池的工作线程中获取结果也并不容易。于是就有了TPL,TPL可被认为是线程池上的又一个抽象层,其对开发人员隐藏了与线程池交互的底层代码,并提供了更细粒度的API。
TPL的核心概念是任务。一个任务代表了一个异步操作,该操作可以通过多种方式运行,可以使用或不使用独立线程运行。
更详细的说明,可以访问
https://docs.microsoft.com/zh-cn/dotnet/standard/parallel-programming/task-parallel-library-tpl
如何创建一个任务
使用Task.Run()方法或Task.Factory.StartNew方法。
创建一个控制台应用程序,输入以下代码
class Program
{
static void Main(string[] args)
{
//使用Task的构造函数
Task task1 = new Task(Task1Method);
task1.Start(); //使用Task.Run
Task.Run(()=> Task2Method()); //使用Task.Factory.StartNew
Task.Factory.StartNew(Task3Method); Console.ReadLine();
} static void Task1Method()
{
Console.WriteLine($"task1 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
} static void Task2Method()
{
Console.WriteLine($"task2 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
} static void Task3Method()
{
Console.WriteLine($"task3 run in thread {System.Threading.Thread.CurrentThread.ManagedThreadId}");
}
}
运行结果如下
以同步方式运行任务
class Program
{
static void Main(string[] args)
{
//主线程运行
TaskMethod("Task1"); Task task2 = new Task(()=>TaskMethod("Task2"));
Task task3 = new Task(()=>TaskMethod("Task3")); //(同步)主线程运行
task2.RunSynchronously(); //(异步)线程池运行
task3.Start();
} static void TaskMethod(string name)
{
Console.WriteLine($"Task {name} is running on a thread id : {System.Threading.Thread.CurrentThread.ManagedThreadId}, " +
$"Is thread pool thread: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
System.Threading.Thread.Sleep(); }
}
运行结果:
使用单独线程的任务
如果任务的代码将长时间运行,可以使用TaskCreationOptions.LongRunning来告诉任务创建一个新线程,而不是使用线程池中的线程
示例代码如下
class Program
{
static void Main(string[] args)
{
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
var t1 = new Task(TaskMethod,TaskCreationOptions.LongRunning);
t1.Start();
} static void TaskMethod()
{
Console.WriteLine(System.Threading.Thread.CurrentThread.IsThreadPoolThread);
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
}
}
运行结果:
使用任务来执行操作
class Program
{
static void Main(string[] args)
{
TaskMethod("Task1");//会阻塞主线程,直到耗时操作完成 Task<int> task = CreateTask("Task 2");
Console.WriteLine(task.Status);
task.Start();//启动任务,并不会阻塞主线程,会继续往下执行
while(!task.IsCompleted)
{
Console.WriteLine(task.Status);
System.Threading.Thread.Sleep();
}
Console.WriteLine(task.Status);
int result = task.Result;
Console.WriteLine($"Result is : {result}");
} static Task<int> CreateTask(string name)
{
return new Task<int>(()=> TaskMethod(name));
} static int TaskMethod(string name)
{
Console.WriteLine($"Task {name} is running on a thread id : {System.Threading.Thread.CurrentThread.ManagedThreadId}, Is thread pool thread: {System.Threading.Thread.CurrentThread.IsThreadPoolThread}");
//模拟耗时操作
System.Threading.Thread.Sleep();
return ;
}
}
运行结果:
组合任务
使用Task< TResult> . ContinueWith方法来创建当另一任务完成时可以执行的延续任务。
当task1执行完成后,把task1返回的结果传递到下一个任务
class Program
{
static void Main(string[] args)
{
Task<int> task1 = new Task<int>(()=> TaskMethod("Task1",)); task1.ContinueWith(x => Console.WriteLine($"The task1 result is {x.Result} " +
$"Thread id is : {System.Threading.Thread.CurrentThread.ManagedThreadId} " +
$"Is Thread pool thread : {System.Threading.Thread.CurrentThread.IsThreadPoolThread} "),TaskContinuationOptions.OnlyOnRanToCompletion);
//TaskContinuationOptions.OnlyOnRanToCompletion 指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。
//更多TaskContinuationOptions可以参考
//https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.taskcontinuationoptions?redirectedfrom=MSDN&view=netframework-4.8 task1.Start();
} static int TaskMethod(string name,int seconds)
{
Console.WriteLine($"Task {name} is running on thread id :{System.Threading.Thread.CurrentThread.ManagedThreadId} " +
$"Is thread pool thread:{System.Threading.Thread.CurrentThread.IsThreadPoolThread} ");
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(seconds));
return DateTime.Now.Second;
}
}
运行结果:
C#使用任务并行库(TPL)的更多相关文章
- 数据流(任务并行库 TPL)
TPL 数据流库向具有高吞吐量和低滞后时间的占用大量 CPU 和 I/O 操作的应用程序的并行化和消息传递提供了基础. 它还能显式控制缓存数据的方式以及在系统中移动的方式. 为了更好地了解数据流编程模 ...
- Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别
Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...
- C#多线程开发-任务并行库04
你好,我是阿辉. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑, ...
- C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)
学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...
- C#并行库(TaskParallelLibrary)用法小结
今天有空,总结一下.NET 4.5并行库(TaskParallelLibrary)用法. 也许C和C++的程序员刚刚开始写C#还习惯于new Thread来新建一个线程,但新建线程需要内存和CPU上下 ...
- C#当中的多线程_任务并行库(上)
复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...
- C#多线程编程系列(五)- 使用任务并行库
目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...
- .NET异步程序设计之任务并行库
目录 1.简介 2.Parallel类 2.0 Parallel类简介 2.1 Parallel.For() 2.2 Parallel.ForEach() 2.3 Parallel.Invoke() ...
随机推荐
- https://pingcap.com/blog-cn/flame-graph/
https://pingcap.com/blog-cn/flame-graph/ 因为 TiKV 是自己内部使用了 jemalloc,并没有用系统的 malloc,所以我们不能直接用 perf 来探查 ...
- MiniUI treeGrid 树节点展开和不展开的性能差别很大
参考API: http://miniui.com/docs/api/index.html#ui=datagrid http://miniui.com/docs/api/index.html#ui=tr ...
- jqGrid怎样冻结指定的列
第一步设置colModel 列内的 frozen: true: 第二步设置表格初始时宽度 shrinkToFit: false, 第三步设置 $gridTable.jqGrid('setFroze ...
- Nexus3.X忘记admin密码找回
一.问题背景 nexus3 这种东西,传完一次,很少动了,很容易忘记密码,不要急有方法找回. 官方网站关于解决该问题的方法: https://support.sonatype.com/hc/en-us ...
- Vue-cli项目结构讲解
|-- build // 项目构建(webpack)相关代码 | |-- build.js // 生产环境构建代码 | |-- check-version.js // 检查node.npm等版本 | ...
- python接入微博第三方API之2接入用户登录和微博发布
python接入微博第三方API之2接入用户登录和微博发布 # coding=utf-8 import requests import json import MySQLdb from datetim ...
- ISO/IEC 9899:2011 条款6.7.4——函数说明符
6.7.4 函数说明符 语法 1.function-specifier: inline _Noreturn 约束 2.函数说明符应该只能被用在对一个函数标识符的声明中. 3.对一个含有外部连接函数的内 ...
- 单例模式以及Python实现
单例模式以及Python实现 单例模式 单例模式就是确保一个类只有一个实例.当你希望整个系统中,某个类只有一个实例时,单例模式就派上了用场.比如,某个服务器的配置信息存在在一个文件中,客户端通过App ...
- svn使用步骤
这里只是记录大概使用过程,操作步骤只供参考,不要按部就班. 1.安装SVN 服务端Setup-Subversion-1.6.5.msi和客户端TortoiseSVN-1.6.5.16974-win32 ...
- [转]Ubuntu 上创建常用磁盘阵列
链接地址:https://www.jianshu.com/p/9a458510593a