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() ...
随机推荐
- [English]常用中英文对照表
Always have been 一直如此 accordingly:相应地 assumption:假定 brace:大括号 branket:中括号 comma:逗号MISC:Miscellaneous ...
- 一个机器绑两个IP可能存在的问题
1.同一网段两个ip 无法绑到一个机器上. 因为会生成两条该网段路由,两个路由用于同网段报文相应,而实际ip选路时只会选择其中一条路由(估计会选择前面那一条)从一个网卡走.这样不管哪个网卡来的局域网内 ...
- hive匹配中文
select regexp_extract('ab中文123测试55..', '[\u4e00-\u9fa5]+', 0) 只提出成功第一段中文汉字,结果为: 中文 select regexp_rep ...
- 空指针异常 自动拆箱 防止 NPE,是程序员的基本修养 本手册明确防止 NPE 是调用者的责任。
空指针异常 空指针异常是指java中的异常类. 中文名 空指针异常 外文名 NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常.这种情况包括: ...
- 改变jupyter notebook的主题背景
https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149( 欢迎关注博 ...
- 【转载】 谷歌集群数据分析 clusterdata-2011-2
原文地址: https://www.twblogs.net/a/5c2dc304bd9eee35b21c418b/zh-cn ------------------------------------- ...
- Spark ML 中 VectorIndexer, StringIndexer等用法(转载)
VectorIndexer 主要作用:提高决策树或随机森林等ML方法的分类效果.VectorIndexer是对数据集特征向量中的类别(离散值)特征(index categorical features ...
- React错误收集
1. Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/ ...
- 生成有目录的pdf
生成有目录的pdf 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://jingyan.baidu.com/article/ff411625c2153512e48237a ...
- html测试页LODOP的内容反复进入打印设计
打印设计是给开发人员使用的工具,用打印设计辅助开发后,打印设计的界面本身的菜单下,可以生成代码,然后把对应的内容信息补充上,拷贝到自己的页面的JS里或存起来,作为模版使用. 也可以关闭打印设计,可返回 ...