C#笔记23:多线程之Task(并行编程)
C#笔记23:多线程之Task(并行编程)
1:Task是什么
2:任务取消
3:TPL 和传统 .NET 异步编程
任务并行库 (TPL) 是 .NET Framework 4 版的 System.Threading 和 System.Threading.Tasks 命名空间中的一组公共类型和 API。TPL 的目的在于简化向应用程序中添加并行性和并发性的过程,从而提高开发人员的工作效率。 TPL 会动态地按比例调节并发程度,以便最有效地使用所有可用的处理器。此外,TPL 还处理工作分区、ThreadPool 上的线程调度、取消支持、状态管理以及其他低级别的细节操作。通过使用 TPL,您可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能。
1:Task是什么
表示一个异步操作。它是异步操作的首选方式。Task是FRAMEWORK4中的新特性,封装了以前的Thread,并管理Thread。
任务由 System.Threading.Tasks..::.Task 类表示。返回值的任务由 System.Threading.Tasks..::.Task<(Of <(TResult>)>) 类表示,该类从 Task 继承。任务对象处理基础结构详细信息,并提供可在任务的整个生存期内从调用线程访问的方法和属性。例如,可以随时访问任务的 Status 属性,以确定它是已开始运行、已完成运行、已取消还是引发了异常。状态由 TaskStatus 枚举表示。
2:任务取消
namespace CancellationWithOCE { using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { Console.WriteLine("Press any key to start. Press 'c' to cancel."); Console.ReadKey(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; // Store references to the tasks so that we can wait on them and // observe their status after cancellation. Task[] tasks = new Task[10]; // Request cancellation of a single task when the token source is canceled. // Pass the token to the user delegate, and also to the task so it can // handle the exception correctly. tasks[0] = Task.Factory.StartNew(() => DoSomeWork(1, token), token); // Request cancellation of a task and its children. Note the token is passed // to (1) the user delegate and (2) as the second argument to StartNew, so // that the task instance can correctly handle the OperationCanceledException. tasks[1] = Task.Factory.StartNew(() => { // Create some cancelable child tasks. for (int i = 2; i < 10; i++) { // For each child task, pass the same token // to each user delegate and to StartNew. tasks[i] = Task.Factory.StartNew(iteration => DoSomeWork((int)iteration, token), i, token); } // Passing the same token again to do work on the parent task. // All will be signaled by the call to tokenSource.Cancel below. DoSomeWork(2, token); }, token); // Give the tasks a second to start. Thread.Sleep(1000); // Request cancellation from the UI thread. if (Console.ReadKey().KeyChar == 'c') { tokenSource.Cancel(); Console.WriteLine("\nTask cancellation requested."); // Optional: Observe the change in the Status property on the task. // It is not necessary to wait on tasks that have canceled. However, // if you do wait, you must enclose the call in a try-catch block to // catch the OperationCanceledExceptions that are thrown. If you do // not wait, no OCE is thrown if the token that was passed to the // StartNew method is the same token that requested the cancellation. #region Optional_WaitOnTasksToComplete try { Task.WaitAll(tasks); } catch (AggregateException e) { // For demonstration purposes, show the OCE message. foreach (var v in e.InnerExceptions) Console.WriteLine("msg: " + v.Message); } // Prove that the tasks are now all in a canceled state. for (int i = 0; i < tasks.Length; i++) Console.WriteLine("task[{0}] status is now {1}", i, tasks[i].Status); #endregion } // Keep the console window open while the // task completes its output. Console.ReadLine(); } static void DoSomeWork(int taskNum, CancellationToken ct) { // Was cancellation already requested? if (ct.IsCancellationRequested) { Console.WriteLine("We were cancelled before we got started."); Console.WriteLine("Press Enter to quit."); ct.ThrowIfCancellationRequested(); } int maxIterations = 1000; // NOTE!!! A benign "OperationCanceledException was unhandled // by user code" error might be raised here. Press F5 to continue. Or, // to avoid the error, uncheck the "Enable Just My Code" // option under Tools > Options > Debugging. for (int i = 0; i < maxIterations; i++) { // Do a bit of work. Not too much. var sw = new SpinWait(); for (int j = 0; j < 3000; j++) sw.SpinOnce(); Console.WriteLine("...{0} ", taskNum); if (ct.IsCancellationRequested) { Console.WriteLine("bye from {0}.", taskNum); Console.WriteLine("\nPress Enter to quit."); ct.ThrowIfCancellationRequested(); } } } } }
3:TPL 和传统 .NET 异步编程
见http://msdn.microsoft.com/zh-cn/library/dd997423.aspx。
微信扫一扫,关注最课程(www.zuikc.com),获取更多我的文章,获取软件开发每日一练