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. SpringMvc使用JavaMail发送邮件,并使用465端口开启ssl加密传输,保证邮件安全

    代码在本地发邮件没任何问题.但部署到服务器,发送邮件显示连接异常.一开始非常懵逼,之后telnet smtp.163.com 25不通,发现是云服务器出于安全考虑,关闭了服务器的25端口,而25端口是 ...

  2. Access与SQL中的IsNull(),IS NULL的区别

    Access也有IsNull函数,但意义和参数却和T-SQL中的不同. 在T-SQL(也就是SQL Server所支持的SQL语言)中,IsNull的作用是把空值替代成指定的值.然而在Access中, ...

  3. ROS学习笔记(二)

    ===================================================== QT工具箱sudo apt-get install ros-kinetic-rqtsudo ...

  4. Django Model 定义语法

    简单用法 from django.db import models class Person(models.Model): first_name = models.CharField(max_leng ...

  5. Python unittest框架实现appium登录

    import unittest from appium.webdriver import webdriver from ddt import data,ddt,unpack class MyTestC ...

  6. 管道式编程(Pipeline Style programming)

    受 F# 中的管道运算符和 C# 中的 LINQ 语法,管道式编程为 C# 提供了更加灵活性的功能性编程.通过使用 扩展函数 可以将多个功能连接起来构建成一个管道. 前言 在 C# 编程中,管道式编程 ...

  7. top命令常用

    top 使用时的命令: Ctrl+L擦除并且重写屏幕. h或者?显示帮助画面,给出一些简短的命令总结说明. k 终止一个进程.系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号. ...

  8. php有关类和对象的相关知识1

    有关类和对象的相关知识 类的自动加载 类的自动加载是指,在外面的页面中,并不需要去“引入”(包含)类文件,但是程序会在需要一个类的时候就自动去“动态加载”该类. 什么叫做“需要一个类”?通常是这样的情 ...

  9. java查询图片显示无图片显示项目默认图片

    /** * 读取图片 * @param request * @param record * @return */ @RequestMapping(params ="method=queryW ...

  10. 在ensp上配置通过Stelnet登录系统

    我们为什么我们要采用Stelent登录? 因为不安全,我们要采用更加安全的方式,双向加密,通过ssh网络安全协议 下面我们开始实验:使用路由器R1模拟PC,作为SSH的客户端:路由器R2作为SSH的服 ...