《2022年C#-Task用法演示教学 .pdf》由会员分享,可在线阅读,更多相关《2022年C#-Task用法演示教学 .pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、C#- Task 用 法名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - - 一:Task 的优势ThreadPool 相比 Thread 来说具备了很多优势,但是ThreadPool 却又存在一些使用上的不方便。比如:1: ThreadPool不支持线程的取消、完成、失败通知等交互性操作;2: ThreadPool不支持线程执行的先后次序;以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概
2、念:Task。Task 在线程池的基础上进行了优化,并提供了更多的 API。在 FCL4.0 中,如果我们要编写多线程程序,Task 显然已经优于传统的方式。以下是一个简单的任务示例:staticvoid Main( string args) Task t = new Task() = Console.WriteLine( 任务开始工作 ); / 模拟工作过程 Thread.Sleep(5000); ); t.Start(); t.ContinueWith(task) = Console.WriteLine( 任务完成,完成时候的状态为: ); Console.WriteLine(IsCanc
3、eled=0tIsCompleted=1tIsFaulted=2, task.IsCanceled, task.IsCompleted, task.IsFaulted); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页 - - - - - - - - - ); Console.ReadKey(); 二:Task 的完成状态任务 Task 有这样一些属性,让我们查询任务完成时的状态:1: IsCanceled,因为被取消而完成;2: IsCompleted,成功完成
4、;3: IsFaulted,因为发生异常而完成需要注意的是,任务并没有提供回调事件来通知完成(像BackgroundWorker 一样),它通过启用一个新任务的方式来完成类似的功能。 ContinueWith方法可以在一个任务完成的时候发起一个新任务,这种方式天然就支持了任务的完成通知:我们可以在新任务中获取原任务的结果值。下面是一个稍微复杂一点的例子,同时支持完成通知、取消、获取任务返回值等功能:staticvoid Main( string args) CancellationTokenSource cts = newCancellationTokenSource(); Task t =
5、new Task() = Add(cts.Token), cts.Token); t.Start(); t.ContinueWith(TaskEnded); / 等待按下任意一个键取消任务 Console.ReadKey(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 8 页 - - - - - - - - - cts.Cancel(); Console.ReadKey(); staticvoid TaskEnded(Task task) Console.Write
6、Line( 任务完成,完成时候的状态为: ); Console.WriteLine(IsCanceled=0tIsCompleted=1tIsFaulted=2, task.IsCanceled, task.IsCompleted, task.IsFaulted); Console.WriteLine( 任务的返回值为: 0 , task.Result); staticint Add(CancellationToken ct) Console.WriteLine( 任务开始 ); int result = 0; while (!ct.IsCancellationRequested) resul
7、t+; Thread.Sleep(1000); return result; 在任务开始后大概3 秒钟的时候按下键盘,会得到如下的输出:任务开始 任务完成,完成时候的状态为:IsCanceled=False IsCompleted=True IsFaulted=False 任务的返回值为: 3你也许会奇怪,我们的任务是通过Cancel 的方式处理,为什么完成的状态IsCanceled 那一栏还是 False 。这是因为在工作任务中,我们对于IsCancellationRequested进行了业务逻辑上的处理,并没有通过名师资料总结 - - -精品资料欢迎下载 - - - - - - - - -
8、 - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 8 页 - - - - - - - - - ThrowIfCancellationRequested方法 进行处理。如果采用后者的方式,如下:staticvoid Main( string args) CancellationTokenSource cts = newCancellationTokenSource(); Task t = new Task() = AddCancleByThrow(cts.Token), cts.Token); t.Start(); t.ContinueWith(Ta
9、skEndedByCatch); / 等待按下任意一个键取消任务 Console.ReadKey(); cts.Cancel(); Console.ReadKey(); staticvoid TaskEndedByCatch(Task task) Console.WriteLine( 任务完成,完成时候的状态为: ); Console.WriteLine(IsCanceled=0tIsCompleted=1tIsFaulted=2, task.IsCanceled, task.IsCompleted, task.IsFaulted); try Console.WriteLine(任务的返回值为
10、: 0 , task.Result); catch (AggregateException e) e.Handle(err) = err is OperationCanceledException); staticint AddCancleByThrow(CancellationToken ct) Console.WriteLine( 任务开始 ); int result = 0; while ( true ) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 8 页 -
11、- - - - - - - - ct.ThrowIfCancellationRequested(); result+; Thread.Sleep(1000); return result; 那么输出为:任务开始 任务完成,完成时候的状态为:IsCanceled=True IsCompleted=True IsFaulted=False 在任务结束求值的方法TaskEndedByCatch中,如果任务是通过ThrowIfCancellationRequested方法结束的,对任务求结果值将会抛出异常OperationCanceledException,而不是得到抛出异常前的结果值。这意味着任务是
12、通过异常的方式被取消掉的,所以可以注意到上面代码的输出中,状态IsCancled 为 True。再一次,我们注意到取消是通过异常的方式实现的,而表示任务中发生了异常的 IsFaulted状态却还是等于 False 。这是因为ThrowIfCancellationRequested是协作式取消方式类型CancellationTokenSource的一个方法, CLR进行 了特殊的处理。 CLR知道这一行程序开发者有意为之的代码,所以不把它看作是一个异常(它被理解为取消)。要得到 IsFaulted等于 True 的状态,我们可以修改 While 循环,模拟一个异常出来:while ( true
13、) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 8 页 - - - - - - - - - /ct.ThrowIfCancellationRequested(); if (result = 5) throw new Exception(error); result+; Thread.Sleep(1000); 模拟异常后的输出为:任务开始 任务完成,完成时候的状态为:IsCanceled=False IsCompleted=True IsFaulted=True 三:任
14、务工厂Task 还支持任务工厂的概念。任务工厂支持多个任务之间共享相同的状态,如取消类型 CancellationTokenSource就是可以被共享的。通过使用任务工厂,可以同时取消一组任务:staticvoid Main( string args) CancellationTokenSource cts = newCancellationTokenSource(); / 等待按下任意一个键取消任务 TaskFactory taskFactory = new TaskFactory(); Task tasks = new Task taskFactory.StartNew() = Add(c
15、ts.Token), taskFactory.StartNew() = Add(cts.Token), taskFactory.StartNew() = Add(cts.Token) ; /CancellationToken.None指示 TasksEnded不能被取消名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 8 页 - - - - - - - - - taskFactory.ContinueWhenAll(tasks, TasksEnded, Cancellati
16、onToken.None); Console.ReadKey(); cts.Cancel(); Console.ReadKey(); staticvoid TasksEnded(Task tasks) Console.WriteLine( 所有任务已完成! ); 以上代码输出为:任务开始 任务开始 任务开始 所有任务已完成(取消)!本建议演示了 Task(任务)和 TaskFactory (任务工厂)的使用方法。Task 甚至进一步优化了后台线程池的调度,加快了线程的处理速度。在FCL4.0 时代,使用多线程,我们理应更多地使用Task。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 8 页 - - - - - - - - -