日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#中的thread和task之Task

發布時間:2023/12/15 C# 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#中的thread和task之Task 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

Task是在.NET Framework 4中添加進來的,這是新的namespace:System.Threading.Tasks;它強調的是adding parallelism and concurrency to applications。

現在都是多核的CPU,在系統內,Task Parallel Library能更有效地利用CPU核心。TPL 會動態地按比例調節并發程度,以便最有效地使用所有可用的處理器。TPL 還處理工作分區、ThreadPool 上的線程調度、取消支持、狀態管理以及其他低級別的細節操作。對比ThreadPool上的Thread并沒有很好地支持Cancel的操作。

在語法上,和lambda表達式更好地結合。

創建Task

顯式創建Task

先看一個簡單的示例:

using System; using System.Threading; using System.Threading.Tasks;public class TaskExample1 {public static void Main(){Thread.CurrentThread.Name = "Main";// 使用lambda方式,之間提供一個用戶delegate,創建一個TaskTask taskA = new Task( () => Console.WriteLine("From taskA."));// StarttaskA.Start();// Output a message from the calling thread.Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);//等待task結束taskA.Wait();} }// From thread 'Main'. // From taskA.

任務對象Task提供可在任務的整個生存期內從調用線程訪問的方法和屬性。例如,可以隨時訪問任務的 Status 屬性,以確定它是已開始運行、已完成運行、已取消還是引發了異常。狀態由 TaskStatus 枚舉表示。

簡化創建并開始的Task操作版本–直接使用一個操作: System.Threading.Tasks.Task.Run()

using System; using System.Threading; using System.Threading.Tasks;public class TaskExample2 {public static void Main(){Thread.CurrentThread.Name = "Main";// Define and run the task.Task taskA = Task.Run( () => Console.WriteLine("From taskA."));// Output a message from the calling thread.Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);taskA.Wait();} } // From thread 'Main'. // From taskA.

TaskFactory創建Task

TPL提供了工廠類TaskFactory,也可用直接創建Task。 一個操作System.Threading.Tasks.TaskFactory.StartNew, 即可完成創建并開始一個Task.

Use this method when creation and scheduling do not have to be separated and you require additional task creaion options or the use of a specific scheduler, or when you need to pass additional state into the task through its AsyncState property, as shown in the following example.

using System; using System.Threading; using System.Threading.Tasks;public class TaskExample3 {public static void Main(){Thread.CurrentThread.Name = "Main";// 創建task并啟動Task taskA = Task.Factory.StartNew(() => Console.WriteLine("From taskA."));// Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);// wait tasktaskA.Wait(); } }// Hello from thread 'Main'. // Hello from taskA.

傳入參數

來自MS的示例:

using System; using System.Threading; using System.Threading.Tasks;public class Example {public static void Main(){Task[] taskArray = new Task[10];for (int i = 0; i < taskArray.Length; i++) {taskArray[i] = Task.Factory.StartNew( (int param) => {Console.WriteLine("Task #{0}.", param);},i );}Task.WaitAll(taskArray); } }

Task返回值

如果一個Task執行方法是有返回值的,可用得到其值。在創建一個task時,其返回的值為Task,表示一個返回類型為T的Task;在taks完成執行后,可用通過Task的Result屬性獲取結果。

public class Task<TResult> : System.Threading.Tasks.Task

來自MS的示例:

using System; using System.Linq; using System.Threading.Tasks;class Program {static void Main(){// lambda表達式創建一個task并執行,并返回值。Task<int> task1 = Task<int>.Factory.StartNew(() => 1);int i = task1.Result;// 返回對象Task<Test> task2 = Task<Test>.Factory.StartNew(() =>{string s = ".NET";double d = 4.0;return new Test { Name = s, Number = d };});Test test = task2.Result;// Return an array produced by a PLINQ queryTask<string[]> task3 = Task<string[]>.Factory.StartNew(() =>{string path = @"C:\Users\Public\Pictures\Sample Pictures\";string[] files = System.IO.Directory.GetFiles(path);var result = (from file in files.AsParallel()let info = new System.IO.FileInfo(file)where info.Extension == ".jpg"select file).ToArray();return result;});foreach (var name in task3.Result)Console.WriteLine(name);}class Test{public string Name { get; set; }public double Number { get; set; }} }

Continue操作

如果一個Task開始執行時間依賴于其它的Task的完成,可以使用Continue系列方法。

來自MS的示例:

using System; using System.Threading.Tasks;public class Example {public static void Main(){ var getData = Task.Factory.StartNew(() => { Random rnd = new Random(); int[] values = new int[100];for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)values[ctr] = rnd.Next();return values;} ); var processData = getData.ContinueWith((x) => {int n = x.Result.Length;long sum = 0;double mean;for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)sum += x.Result[ctr];mean = sum / (double) n;return Tuple.Create(n, sum, mean);} ); var displayData = processData.ContinueWith((x) => {return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",x.Result.Item1, x.Result.Item2, x.Result.Item3);} ); Console.WriteLine(displayData.Result);} }// 輸出: // N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82

而且,可以使用更簡化的寫法.

using System; using System.Threading.Tasks;public class Example {public static void Main(){ var displayData = Task.Factory.StartNew(() => { Random rnd = new Random(); int[] values = new int[100];for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)values[ctr] = rnd.Next();return values;} ). ContinueWith((x) => {int n = x.Result.Length;long sum = 0;double mean;for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)sum += x.Result[ctr];mean = sum / (double) n;return Tuple.Create(n, sum, mean);} ). ContinueWith((x) => {return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",x.Result.Item1, x.Result.Item2, x.Result.Item3);} ); Console.WriteLine(displayData.Result);} }

Cancel操作

在TPL中,為Task能cancel執行,提供了CancellationTokenSource和CancellationToken;
需要完成的工作是:在Task的action執行方法內,周期性地檢查CancellationToken的IsCancellationRequested屬性。
示例:

private var tokenSource = new CancellationTokenSource();public void Start(){var token = tokenSource.Token;for (int i = 0; i<5; i++>) {Task t = Task.Factory.StartNew( () => DoSomeWork(i, token), token);Console.WriteLine("Task {0} executing", t.Id);}}public void Stop(){var token = tokenSource.Token;tokenSource.Cancel();}void DoSomeWork(int taskNum, CancellationToken ct){// 先檢查,調度進入時,是否cancel了。if (ct.IsCancellationRequested == true) {Console.WriteLine("Task {0} was cancelled before it got started.",taskNum);ct.ThrowIfCancellationRequested(); // 拋出異常-- 或者 return} // 正式開始任務。 int maxIterations = 100;// NOTE!!! A "TaskCanceledException was unhandled for (int i = 0; i <= maxIterations; i++) {// var sw = new SpinWait();for (int j = 0; j <= 100; j++)sw.SpinOnce();if (ct.IsCancellationRequested) {Console.WriteLine("Task {0} cancelled", taskNum);ct.ThrowIfCancellationRequested(); //拋出異常-- 或者 return} } }

總結

以上是生活随笔為你收集整理的C#中的thread和task之Task的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。