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. php递归注意事项

    /* 循环去除字符串左边的0 */ function removeLeftZero($str){ if($str['0'] == '0'){ $str = substr($str, '1'); rem ...

  2. 有关 MyEclipse->export runnable jar file选项 launch configuration里面没有可以选择的东西的解决方法

    为什么eclipse里export-->runnable jar file-->的launch configuration里面没有可以选择的东西或者新写的main方法却找不到呢? 将你程序 ...

  3. synchronized 同步对象概念

    解决上述问题之前,先理解synchronized关键字的意义如下代码:   Object someObject =new Object(); synchronized (someObject){ // ...

  4. oraagent.bin High Memory Usage as Dependent Listener was Removed/Renamed

    Grid Infrastructure oraagent.bin process using huge amount of memory and  forking huge number of thr ...

  5. 123457123456#1#----com.MC.CarWashKidsGames234----前拼后广--洗车游戏mc-mc1111

    com.MC.CarWashKidsGames234----前拼后广--洗车游戏mc-mc1111

  6. go micro rpc 直接调用 返回500 错误

    开启网关时需要 加上 flags micro api -handle=api --enable_rpc

  7. ASP.NET全球化与本地化 c#多国语言的支持 (项目支持多国语言的开发)

    ASP.NET 2.0及以上的开发平台,为全球化本地化应用程序提供了工具,而且实现起来非常简单.以下内容是使用c#,按照帮助一步步做的,将为初学者提供详细的实现步骤. 一 几个必要概念 (一) 支持全 ...

  8. 【linux学习笔记四】文件搜索命令

    一 文件搜索 locate //在后台数据库中按文件名搜索 搜索速度更快 locate 文件名 //locate命令所搜索的后台数据库 /var/lib/mlocate //更新数据库 updated ...

  9. MySQL报错argument out of range 1055解决办法

    参考:https://www.cnblogs.com/liangbenstudy/p/10246895.html MySQL 5.7.22查询时候报错 argument out of range 报错 ...

  10. STM32F405的 ADC参考电压选择问题

    1. STM32F405没有参考电压的输入引脚,那么可能是接的VDDA和VSSA 2. 看下文档的说明