<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
ThreadPool相比Thread來說具備了很多優勢,但是ThreadPool卻又存在一些使用上的不方便,例如:
.NET Framework 在4.0的時候提供了一個功能更強大的概念:Task。Task在ThreadPool的基礎上進行了優化,並提供了更多的API。看下面一個簡單的範例:
using System; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { // 建立Task Task t = new Task(() => { Console.WriteLine("任務開始工作....."); Thread.Sleep(5000); }); // 啟動 t.Start(); t.ContinueWith((task) => { Console.WriteLine("任務完成,完成時候的狀態為:"); Console.WriteLine("IsCanceled={0}tIsCompleted={1}tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted); }); Console.WriteLine("啟動"); Console.ReadKey(); } } }
Task建立的任務可以分為有返回值和無返回值兩種。
先看一下Task的定義:
可以看到Task建構函式的引數是Action委託。所以使用Task建立任務的程式碼如下:
using System; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 Task task = new Task(() => TaskMethod("Task 1")); Console.WriteLine("before start status:"+task.Status); // Task建立的任務必須呼叫start方法才能啟動 task.Start(); Console.WriteLine("after start status:" + task.Status); #endregion Console.ReadKey(); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } } }
程式執行結果:
注:任務的狀態,Start之前為Created,Start之後為WaitingToRun。
Task.Run建立的任務可以執行啟動:
using System; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 //Task task = new Task(() => TaskMethod("Task 1")); //Console.WriteLine("before start status:"+task.Status); //// Task建立的任務必須呼叫start方法才能啟動 //task.Start(); //Console.WriteLine("after start status:" + task.Status); #endregion #region 2、使用Task.Run建立任務 Task.Run(() => TaskMethod("Task Run")); #endregion Console.ReadKey(); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } } }
程式執行結果:
using System; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 //Task task = new Task(() => TaskMethod("Task 1")); //Console.WriteLine("before start status:"+task.Status); //// Task建立的任務必須呼叫start方法才能啟動 //task.Start(); //Console.WriteLine("after start status:" + task.Status); #endregion #region 2、使用Task.Run建立任務 // Task.Run(() => TaskMethod("Task Run")); #endregion #region 3、使用Factory建立任務 // 使用Task.Factory建立 Task.Factory.StartNew(() => TaskMethod("Task 4")); //標記為長時間執行任務,則任務不會使用執行緒池,而在單獨的執行緒中執行。 Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); // 範例化TaskFactory物件,然後建立 TaskFactory factory = new TaskFactory(); factory.StartNew(() => TaskMethod("Task 6")); #endregion Console.ReadKey(); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } } }
程式執行結果:
程式碼如下:
using System; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 //Task task = new Task(() => TaskMethod("Task 1")); //Console.WriteLine("before start status:"+task.Status); //// Task建立的任務必須呼叫start方法才能啟動 //task.Start(); //Console.WriteLine("after start status:" + task.Status); #endregion #region 2、使用Task.Run建立任務 // Task.Run(() => TaskMethod("Task Run")); #endregion #region 3、使用Task.Factory建立任務 //Task.Factory.StartNew(() => TaskMethod("Task 4")); ////標記為長時間執行任務,則任務不會使用執行緒池,而在單獨的執行緒中執行。 //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); #endregion #region 4、建立帶返回值的任務 TaskMethodReturn("Main Thread Task"); // 建立帶返回值的Task Task<int> task = CreateTask("Task 1"); // 啟動 task.Start(); // 獲取返回值 int result1 = task.Result; Console.WriteLine($"Task 1 Result is:{result1}"); Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2")); task2.Start(); int result2 = task2.Result; Console.WriteLine($"Task 2 Result is:{result2}"); int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result; Console.WriteLine($"Task 3 Result is:{result3}"); int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result; Console.WriteLine($"Task 4 Result is:{result4}"); #endregion Console.ReadKey(); } /// <summary> /// 返回一個Task<int> /// </summary> /// <param name="name"></param> /// <returns></returns> static Task<int> CreateTask(string name) { // 引數是Func<int> return new Task<int>(() => TaskMethodReturn(name)); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } static int TaskMethodReturn(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(2)); return 42; } } }
程式執行結果:
我們在文章開始的時候說過,Task是基於ThreadPool的,那麼怎麼證明呢?看下面的程式碼:
/// <summary> /// 測試Task的執行緒來自於ThreadPool /// </summary> static void Test() { // 設定執行緒池中最大的執行緒數 ThreadPool.SetMaxThreads(6, 6); // 建立Task的集合 List<Task> taskList = new List<Task>(); // 建立int型別的集合,用於存放執行緒ID List<int> threadIdList = new List<int>(); // 使用Task迴圈建立50個執行緒 for (int i = 0; i < 30; i++) { int k = i; Task task = Task.Run(() => { // 當前執行緒ID加入到集合中 threadIdList.Add(Thread.CurrentThread.ManagedThreadId); Console.WriteLine($"this is {k} 迴圈 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); // 休眠 Thread.Sleep(200); }); // 把task加入到集合中 taskList.Add(task); } // 等待所有的執行緒執行完 Task.WaitAll(taskList.ToArray()); // 輸出總數量 Console.WriteLine($"執行緒總數:{threadIdList.Distinct().Count()}"); }
程式執行結果:
從結果中可以看出,Task中的執行緒確實是來自於ThreadPool。
我們以下面的一個例子來講解Task中比較常見的幾個方法。多名開發者合作開發一個專案,每個人負責一個模組的開發,我們可以把這個過程認為是多執行緒,程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 //Task task = new Task(() => TaskMethod("Task 1")); //Console.WriteLine("before start status:"+task.Status); //// Task建立的任務必須呼叫start方法才能啟動 //task.Start(); //Console.WriteLine("after start status:" + task.Status); #endregion #region 2、使用Task.Run建立任務 // Task.Run(() => TaskMethod("Task Run")); #endregion #region 3、使用Factory建立任務 // 使用Task.Factory建立 //Task.Factory.StartNew(() => TaskMethod("Task 4")); ////標記為長時間執行任務,則任務不會使用執行緒池,而在單獨的執行緒中執行。 //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); // 範例化TaskFactory物件,然後建立 //TaskFactory factory = new TaskFactory(); //factory.StartNew(() => TaskMethod("Task 6")); #endregion #region 4、建立帶返回值的任務 //TaskMethodReturn("Main Thread Task"); //// 建立帶返回值的Task //Task<int> task = CreateTask("Task 1"); //// 啟動 //task.Start(); //// 獲取返回值 //int result1 = task.Result; //Console.WriteLine($"Task 1 Result is:{result1}"); //Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2")); //task2.Start(); //int result2 = task2.Result; //Console.WriteLine($"Task 2 Result is:{result2}"); //int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result; //Console.WriteLine($"Task 3 Result is:{result3}"); //int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result; //Console.WriteLine($"Task 4 Result is:{result4}"); #endregion #region 測試Task執行緒是來自於ThreadPool // Test(); #endregion // 合作開發專案,每個人負責一個模組,可以認為是多執行緒 Console.WriteLine("開始合作開發一個大專案!"); Task.Run(() => CodingShow("Tom", "搭建微服務架構!")); Task.Run(() => CodingShow("Kevin", "微信介面!")); Task.Run(() => CodingShow("Jack", "搭建後臺框架!")); Task.Run(() => CodingShow("Alex", "設計資料庫!")); Task.Run(() => CodingShow("Lee", "支付寶介面對接!")); Console.ReadKey(); } /// <summary> /// 返回一個Task<int> /// </summary> /// <param name="name"></param> /// <returns></returns> static Task<int> CreateTask(string name) { // 引數是Func<int> return new Task<int>(() => TaskMethodReturn(name)); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } static int TaskMethodReturn(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(2)); return 42; } /// <summary> /// 測試Task的執行緒來自於ThreadPool /// </summary> static void Test() { // 設定執行緒池中最大的執行緒數 ThreadPool.SetMaxThreads(6, 6); // 建立Task的集合 List<Task> taskList = new List<Task>(); // 建立int型別的集合,用於存放執行緒ID List<int> threadIdList = new List<int>(); // 使用Task迴圈建立50個執行緒 for (int i = 0; i < 30; i++) { int k = i; Task task = Task.Run(() => { // 當前執行緒ID加入到集合中 threadIdList.Add(Thread.CurrentThread.ManagedThreadId); Console.WriteLine($"this is {k} 迴圈 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); // 休眠 Thread.Sleep(200); }); // 把task加入到集合中 taskList.Add(task); } // 等待所有的執行緒執行完 Task.WaitAll(taskList.ToArray()); // 輸出總數量 Console.WriteLine($"執行緒總數:{threadIdList.Distinct().Count()}"); } /// <summary> /// 模擬Coding過程 /// </summary> /// <param name="name"></param> /// <param name="projectName"></param> static void CodingShow(string name, string projectName) { Console.WriteLine($"CodingShow Start {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} "); long lResult = 0; for (int i = 0; i < 1_000_000_000; i++) { lResult += i; } Console.WriteLine($"CodingShow End {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} "); } } }
程式執行結果:
這時需求發生了變化,所有的模組都開發完成以後,開始搭建測試環境,修改程式碼如下:
// 合作開發專案,每個人負責一個模組,可以認為是多執行緒 Console.WriteLine("開始合作開發一個大專案!"); Task.Run(() => CodingShow("Tom", "搭建微服務架構!")); Task.Run(() => CodingShow("Kevin", "微信介面!")); Task.Run(() => CodingShow("Jack", "搭建後臺框架!")); Task.Run(() => CodingShow("Alex", "設計資料庫!")); Task.Run(() => CodingShow("Lee", "支付寶介面對接!")); Console.WriteLine("所有模組都開發完成,開始搭建測試環境");
程式執行結果:
可以看到顯然不是我們想要的結果,模組開發工作還沒有結束就搭建測試環境,即子執行緒還沒有結束,主執行緒就已經結束了。要想實現我們想要的效果,那麼必須使主執行緒等待所有子執行緒都結束以後,主執行緒才能結束。
WaitAll()表示等待所有的Task都執行完成。看WaitAll()的定義:
WaitAll()方法有很多過載,我們在這裡使用第一個過載方法,即引數是Task[]陣列。檢視Run()方法的定義時,我們會發現Run()方法的返回值就是Task型別,我們使用WaitAll()修改上面的程式碼:
// 定義一個Task型別的集合 List<Task> taskList = new List<Task>(); Console.WriteLine("開始合作開發一個大專案!"); taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); // 等待所有模組都開發完成,才能搭建測試環境 Task.WaitAll(taskList.ToArray()); Console.WriteLine("所有模組都開發完成,開始搭建測試環境");
程式執行結果:
WaitAll()會使程式產生卡頓。
載入首頁資訊的時候可以使用WaitAll()方法。一個首頁資訊可能來自於幾部分的資料,每一部分的資料對應一個執行緒,只有所有的執行緒都執行完畢才顯示首頁資訊。
這時需求又發生改變了:某一個模組開發完成以後就搭建測試環境。這時候就可以使用WaitAny()了。WaitAny()表示等待其中任何一個任務完成就會進入下一個任務,定義如下:
修改後的程式碼如下:
// 定義一個Task型別的集合 List<Task> taskList = new List<Task>(); Console.WriteLine("開始合作開發一個大專案!"); taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); // 等待所有模組都開發完成,才能搭建測試環境 Task.WaitAny(taskList.ToArray()); Console.WriteLine("有模組開發完成,開始搭建測試環境");
程式執行結果:
可以看到:設計資料庫模組完成以後,就開始搭建測試環境了。如何需求。
WaitAny()會使程式產生卡頓。
有一個列表資料,資料可以來源於介面、快取、資料庫等,可以開啟多個執行緒,只要有一個執行緒執行完畢就可以繼續執行下面的步驟,這時就可以使用WaitAny()。
WaitAll()會卡頓介面,那麼有沒有不卡頓介面的呢?ContinueWhenAll和WaitAll實現的效果一樣,程式碼如下:
List<Task> taskList = new List<Task>(); Console.WriteLine("開始合作開發一個大專案!"); taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); TaskFactory factory = new TaskFactory(); factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模組開發完成"));
程式執行結果:
ContinueWhenAny實現的效果和WaitAny一樣,ContinueWhenAny不會卡頓介面,程式碼如下:
List<Task> taskList = new List<Task>(); Console.WriteLine("開始合作開發一個大專案!"); taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); TaskFactory factory = new TaskFactory(); factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一個模組開發完成"));
程式執行結果:
ContinueWhenAll()和ContinueWhenAny()都會開啟一個新的執行緒。
ContinueWith表示回撥,程式碼如下:
Task.Run(() => { Console.WriteLine("任務執行完成"); }).ContinueWith(p=> { Task.Run(() => { Console.WriteLine("執行回撥"); }); });
程式執行結果:
程式完整程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace TaskDemo { class Program { static void Main(string[] args) { #region 1、使用Task建立任務 //Task task = new Task(() => TaskMethod("Task 1")); //Console.WriteLine("before start status:"+task.Status); //// Task建立的任務必須呼叫start方法才能啟動 //task.Start(); //Console.WriteLine("after start status:" + task.Status); #endregion #region 2、使用Task.Run建立任務 // Task.Run(() => TaskMethod("Task Run")); #endregion #region 3、使用Factory建立任務 // 使用Task.Factory建立 //Task.Factory.StartNew(() => TaskMethod("Task 4")); ////標記為長時間執行任務,則任務不會使用執行緒池,而在單獨的執行緒中執行。 //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); // 範例化TaskFactory物件,然後建立 //TaskFactory factory = new TaskFactory(); //factory.StartNew(() => TaskMethod("Task 6")); #endregion #region 4、建立帶返回值的任務 //TaskMethodReturn("Main Thread Task"); //// 建立帶返回值的Task //Task<int> task = CreateTask("Task 1"); //// 啟動 //task.Start(); //// 獲取返回值 //int result1 = task.Result; //Console.WriteLine($"Task 1 Result is:{result1}"); //Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2")); //task2.Start(); //int result2 = task2.Result; //Console.WriteLine($"Task 2 Result is:{result2}"); //int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result; //Console.WriteLine($"Task 3 Result is:{result3}"); //int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result; //Console.WriteLine($"Task 4 Result is:{result4}"); #endregion #region 測試Task執行緒是來自於ThreadPool // Test(); #endregion // 合作開發專案,每個人負責一個模組,可以認為是多執行緒 // 無序 //Console.WriteLine("開始合作開發一個大專案!"); //Task.Run(() => CodingShow("Tom", "搭建微服務架構!")); //Task.Run(() => CodingShow("Kevin", "微信介面!")); //Task.Run(() => CodingShow("Jack", "搭建後臺框架!")); //Task.Run(() => CodingShow("Alex", "設計資料庫!")); //Task.Run(() => CodingShow("Lee", "支付寶介面對接!")); //Console.WriteLine("所有模組都開發完成,開始搭建測試環境"); #region WaitAll //// 定義一個Task型別的集合 //List<Task> taskList = new List<Task>(); //Console.WriteLine("開始合作開發一個大專案!"); //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); //taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); //// 等待所有模組都開發完成,才能搭建測試環境 //Task.WaitAll(taskList.ToArray()); //Console.WriteLine("所有模組都開發完成,開始搭建測試環境"); #endregion #region WaitAny // 定義一個Task型別的集合 //List<Task> taskList = new List<Task>(); //Console.WriteLine("開始合作開發一個大專案!"); //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); //taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); //// 等待所有模組都開發完成,才能搭建測試環境 //Task.WaitAny(taskList.ToArray()); //Console.WriteLine("有模組開發完成,開始搭建測試環境"); #endregion #region ContinueWhenAll //List<Task> taskList = new List<Task>(); //Console.WriteLine("開始合作開發一個大專案!"); //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); //taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); //TaskFactory factory = new TaskFactory(); //factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模組開發完成")); #endregion #region ContinueWhenAll //List<Task> taskList = new List<Task>(); //Console.WriteLine("開始合作開發一個大專案!"); //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!"))); //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信介面!"))); //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建後臺框架!"))); //taskList.Add(Task.Run(() => CodingShow("Alex", "設計資料庫!"))); //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶介面對接!"))); //TaskFactory factory = new TaskFactory(); //factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一個模組開發完成")); #endregion #region ContinueWith Task.Run(() => { Console.WriteLine("任務執行完成"); }).ContinueWith(p=> { Task.Run(() => { Console.WriteLine("執行回撥"); }); }); #endregion Console.ReadKey(); } /// <summary> /// 返回一個Task<int> /// </summary> /// <param name="name"></param> /// <returns></returns> static Task<int> CreateTask(string name) { // 引數是Func<int> return new Task<int>(() => TaskMethodReturn(name)); } static void TaskMethod(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); } static int TaskMethodReturn(string name) { Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(2)); return 42; } /// <summary> /// 測試Task的執行緒來自於ThreadPool /// </summary> static void Test() { // 設定執行緒池中最大的執行緒數 ThreadPool.SetMaxThreads(6, 6); // 建立Task的集合 List<Task> taskList = new List<Task>(); // 建立int型別的集合,用於存放執行緒ID List<int> threadIdList = new List<int>(); // 使用Task迴圈建立50個執行緒 for (int i = 0; i < 30; i++) { int k = i; Task task = Task.Run(() => { // 當前執行緒ID加入到集合中 threadIdList.Add(Thread.CurrentThread.ManagedThreadId); Console.WriteLine($"this is {k} 迴圈 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); // 休眠 Thread.Sleep(200); }); // 把task加入到集合中 taskList.Add(task); } // 等待所有的執行緒執行完 Task.WaitAll(taskList.ToArray()); // 輸出總數量 Console.WriteLine($"執行緒總數:{threadIdList.Distinct().Count()}"); } /// <summary> /// 模擬Coding過程 /// </summary> /// <param name="name"></param> /// <param name="projectName"></param> static void CodingShow(string name, string projectName) { Console.WriteLine($"CodingShow Start {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} "); long lResult = 0; for (int i = 0; i < 1_000_000_000; i++) { lResult += i; } Console.WriteLine($"CodingShow End {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} "); } } }
到此這篇關於C#多執行緒程式設計Task用法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45