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)的更多相关文章

  1. 数据流(任务并行库 TPL)

    TPL 数据流库向具有高吞吐量和低滞后时间的占用大量 CPU 和 I/O 操作的应用程序的并行化和消息传递提供了基础. 它还能显式控制缓存数据的方式以及在系统中移动的方式. 为了更好地了解数据流编程模 ...

  2. 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 ...

  3. C#多线程开发-任务并行库04

    你好,我是阿辉. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑, ...

  4. 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). 其次是 ...

  5. C#并行库(TaskParallelLibrary)用法小结

    今天有空,总结一下.NET 4.5并行库(TaskParallelLibrary)用法. 也许C和C++的程序员刚刚开始写C#还习惯于new Thread来新建一个线程,但新建线程需要内存和CPU上下 ...

  6. C#当中的多线程_任务并行库(上)

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  7. C#多线程编程系列(五)- 使用任务并行库

    目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...

  8. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  9. .NET异步程序设计之任务并行库

    目录 1.简介 2.Parallel类 2.0 Parallel类简介 2.1 Parallel.For() 2.2 Parallel.ForEach() 2.3 Parallel.Invoke() ...

随机推荐

  1. MYSQL双主模式,触发器(trigger)不可见问题

    MYSQL版本信息: Your MySQL connection id is 71851 Server version: 5.7.24-log MySQL Community Server (GPL) ...

  2. Centos7 安装 weblogic12.2.1.0.0

    下载地址:地址:http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html 下载最新的we ...

  3. openresty开发系列10--openresty的简单介绍及安装

    openresty开发系列10--openresty的简单介绍及安装 一.Nginx优点 十几年前,互联网没有这么火,软件外包开发,信息化建设,帮助企业做无纸化办公,收银系统,工厂erp,c/s架构偏 ...

  4. 重启WMS服务

    一.重启API服务 查看进程ps ef|grep java 进入目录 cd /usr/local/tomcat-api/bin ./shutdown.sh ps –ef|grep 查看服务是否真的停止 ...

  5. C++ 理解函数对象与lambda表达式

    参考<21天学通C++>第21与第22章节,对函数对象进行介绍,同时通过lambda表达式这一匿名函数对象的简洁方式加深对函数对象的理解.本篇博文的主要内容是: (1) 函数对象的概念: ...

  6. 封装transform函数(设置和获取transform的属性和属性值)

    (function (w) { /** * 设置或者获取元素的transform属性值 * @param node 要设置的元素 * @param param 变换属性: translate\scal ...

  7. 无聊的活动/缘生意转(2018 Nova OJ新年欢乐赛B题)解题报告

    题目2(下面的太抓 我重新写了个背景 其他都一样) 无聊的活动 JLZ老师不情愿的参加了古风社一年一度的活动,他实在不觉得一群学生跳舞有什么好看,更不明白坐在身后的学生为什么这么兴奋(看小姐姐),于是 ...

  8. FutureTask源码阅读

    FutureTask功能用法 类结构 源码中详细说明了FutureTask生命周期状态及变化 /** * The run state of this task, initially NEW. The ...

  9. Ordered Neurons: Integrating Tree Structures Into Recurrent Neural Networks

    这是一篇发表在ICLR2019上的论文,并且还是ICLR2019的Best paper之一.该论文提出了能够学习树结构信息的ON-LSTM模型,这篇论文的开源代码可以在GitHub找到. 自然语言都是 ...

  10. Java注解-注解处理器、servlet3.0|乐字节

    大家好,我是乐字节的小乐,上次给大家带来了Java注解-元数据.注解分类.内置注解和自定义注解|乐字节,这次接着往下讲注解处理器和servlet3.0 一.注解处理器 使用注解的过程中,很重要的一部分 ...