Content

.Net中Task Parallel Library的基本用法(.net framework 3.5有必要装吗)满满干货

文章摘要

这篇文章介绍了如何使用**Task Parallel Library(TPL)**进行异步编程和多线程操作。文章主要涵盖以下内容: 1. **Task的基本构造**:通过`Task`对象和`TaskFactory`工厂方法创建任务,可以在主线程同时启动多个子任务。 2. **任务的启动方式**: - 使用`Task.Factory.StartNew()`静态方法启动任务。 - 通过`Task`对象的`Start()`方法启动任务。 - 使用委托(Delegate)启动任务。 3. **任务的执行与结果获取**: - 使用`Task.Run()`静态方法启动任务。 - 通过`Task.Result`获取任务的执行结果。 4. **任务的条件执行与结果处理**: - 使用`ContinueWith`方法在任务完成时执行后续代码。 - 使用`WaitAll`方法等待所有任务完成。 5. **任务的取消与中断**: - 使用`CancellationToken`手动取消任务。 6. **嵌套任务与复杂场景**: - 使用嵌套`Task`实现复杂任务处理。 - 通过`Task`工厂方法实现任务依赖。 7. **实际应用示例**: - 使用`DownloadAsync`方法在后台下载网页。 - 通过UI线程下载数据,保持界面无影响。 总结:文章详细讲解了如何利用TPL实现高效的异步编程,涵盖任务启动、执行、结果处理、条件执行、任务管理等核心功能,并提供了多个实际应用示例。



我们知道,每个应用程序就是一个进程,一个进程有多个线程。Task Parallel Library为我们的异步编程、多线程编程提供了强有力的支持,它允许一个主线程运行的同时,另外的一些线程或Task也同时运行。本篇体验基本用法。

Taks的构造函数接收的类型是Action,也就是一个委托。

static void Main(string[] args) { var t1=new Task(()=> { Console.WriteLine(“任务1开始”); Thread.Sleep(1000); Console.WriteLine(“任务1结束”); }); t1.Start(); Console.ReadKey(); }

如果把方法放到外面。

static void Main(string[] args) { var t1=new Task(()=> DoSth(1,2000)); t1.Start(); Console.ReadKey(); } static void DoSth(int id, int sleepTime) { Console.WriteLine(“任务{0}开始”,id); Thread.Sleep(sleepTime); Console.WriteLine(“任务{0}结束”,id); }

如果有多个Task同时执行。

static void Main(string[] args) { var t1=new Task(()=> DoSth(1,2000)); t1.Start(); var t2=new Task(()=> DoSth(2, 1500)); t2.Start(); var t3=new Task(()=> DoSth(3, 3000)); t3.Start(); Console.ReadKey(); }

如果有很多Task,每个Task手动启动的话很费事,Task Parallel Library为我们准备了Task工厂。

static void Main(string[] args) { var t1=Task.Factory.StartNew(()=> DoSth(1, 2000)); var t2=Task.Factory.StartNew(()=> DoSth(2, 1500)); var t3=Task.Factory.StartNew(()=> DoSth(3, 3000)); Console.ReadKey(); }

如果我们想在一个任务结束之后立即执行某个任务,可以使用ContinueWith方法。

static void Main(string[] args) { var t1=Task.Factory.StartNew(()=> DoSth(1, 2000)).ContinueWith((pre)=> DoOtherThing(4,2000)); var t2=Task.Factory.StartNew(()=> DoSth(2, 1500)); var t3=Task.Factory.StartNew(()=> DoSth(3, 3000)); Console.ReadKey(); } static void DoSth(int id, int sleepTime) { Console.WriteLine(“任务{0}开始”,id); Thread.Sleep(sleepTime); Console.WriteLine(“任务{0}结束”,id); } static void DoOtherThing(int id, int sleepTime) { Console.WriteLine(“其他任务{0}开始”, id); Thread.Sleep(sleepTime); Console.WriteLine(“其他任务{0}结束”, id); }

如果希望等待所有的Task执行完毕,使用WaitAll方法。

static void Main(string[] args) { var t1=Task.Factory.StartNew(()=> DoSth(1, 2000)); var t2=Task.Factory.StartNew(()=> DoSth(2, 1500)); var t3=Task.Factory.StartNew(()=> DoSth(3, 3000)); var taskList=new List<Task> {t1, t2, t3}; Task.WaitAll(taskList.ToArray()); Console.WriteLine(“我是在所有Task执行完毕后才执行的”); Console.ReadKey(); }

如果想手动取消结束某个Task,需要为方法带上CancellationToken类型参数。

static void Main(string[] args) { var source=new CancellationTokenSource(); try { var t1= Task.Factory.StartNew(()=> DoSth(1, 1000, source.Token)) .ContinueWith((pre)=> DoOtherThing(2, 2000)); source.Cancel(); } catch (Exception ex) { Console.WriteLine(ex.GetType()); } Console.WriteLine(“haha”); Console.ReadKey(); } static void DoSth(int id, int sleepTime, CancellationToken token) { if (token.IsCancellationRequested) { Console.WriteLine(“任务被取消”); token.ThrowIfCancellationRequested(); } Console.WriteLine(“任务{0}开始”,id); Thread.Sleep(sleepTime); Console.WriteLine(“任务{0}结束”,id); } static void DoOtherThing(int id, int sleepTime) { Console.WriteLine(“其他任务{0}开始”, id); Thread.Sleep(sleepTime); Console.WriteLine(“其他任务{0}结束”, id); }

如何从Task从获取方法的返回结果呢?

static void Main(string[] args) { Console.WriteLine(“开始计算”); Task<int> t=Task.Factory.StartNew(()=> Sum(1, 2)); Console.WriteLine(“等待结果”); Console.WriteLine(t.Result); Console.ReadKey(); } static int Sum(int a, int b) { return a + b; }

后面一个Task获取前面一个Task的返回值。

static void Main(string[] args) { Task<string> firstTask=Task.Factory.StartNew<string>(()=> { Console.WriteLine(“第一个任务开始”); return “hi from the one”; }); Task secondTask=firstTask.ContinueWith((prevoursTask)=> { Console.WriteLine(“这里是第二个任务,获取到第一个任务的返回值是{0}”,prevoursTask.Result,TaskContinuationOptions.OnlyOnRanToCompletion); }); secondTask.Wait(); Console.ReadKey(); }

等待所有Task完成。

static void Main(string[] args) { var t1=Task.Factory.StartNew(()=> { Console.WriteLine(“第一个任务”); Thread.Sleep(1000); }); var t2=Task.Factory.StartNew(()=> { Console.WriteLine(“第二个任务”); Thread.Sleep(1000); }); var taskList=new List<Task> {t1, t2}; Task.Factory.ContinueWhenAll(taskList.ToArray(), (t)=> { Console.WriteLine(“所有任务完成我就出来”); }); Console.ReadKey(); }

如果是嵌套Task。

static void Main(string[] args) { Task.Factory.StartNew(()=> { Task child=Task.Factory.StartNew(()=> { Console.WriteLine(“我是子任务”); }, TaskCreationOptions.AttachedToParent); }).Wait(); Console.ReadKey(); }

1、通过Task.Factory.StartNew方法。

static void Main(string[] args) { Task.Factory.StartNew(()=> SaySth(“hello”)); Console.ReadKey(); } static void SaySth(string msg) { Console.WriteLine(msg); }

2、通过Task的Start实例方法

static void Main(string[] args) { var t=new Task(()=> SaySth(“hello”)); t.Start(); Console.ReadKey(); }

或者干脆用委托。

static void Main(string[] args) { Task t=new Task(delegate {SaySth(“hello”);}); t.Start(); Console.ReadKey(); }

3、Task的静态方法Run

static void Main(string[] args) { Task t=Task.Run(()=> SaySth(“hello”)); Console.ReadKey(); } static void SaySth(string msg) { Console.WriteLine(msg); }

比如说要下载某个页面,在保持当前UI界面无影响的情况下,使用Task在后台启动任务下载某个页面。

static void Main(string[] args) { Console.WriteLine(“界面内容”); Task<string> r=DownloadAsync(“http://www.baidu.com”); while (!r.IsCompleted) { Console.Write(“.”); Thread.Sleep(250); } Console.WriteLine(r.Result); Console.ReadKey(); } private static string DownloadWebPage(string url) { WebRequest request=WebRequest.Create(url); WebResponse response=request.GetResponse(); var reader=new StreamReader(response.GetResponseStream()); return reader.ReadToEnd(); } private static Task<string> DownloadAsync(string url) { return Task.Factory.StartNew(()=> DownloadWebPage(url)); }

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:ASP.NET?Core在Task中使用IServiceProvider的问题解析.Net通过TaskFactory.FromAsync简化APM.NET中的async和await关键字使用及Task异步调用实例.Net中Task Parallel Library的进阶用法