標籤:row cat ons 選擇 ros 學習 異常 stat logs
一 任務
可以調用ThreadPool的QueueUserWorkItem方法發起一次非同步計算限制操作.
但這個技術有很多限制.最大的問題是沒有內建的機制讓你知道操作在什麼時候
完成和操作完成時的傳回值.為了克服這些限制(並解決其他一些問題),Microsoft
引入了任務的概念.
1 //調用QueueUserWorkItem2 ThreadPool.QueueUserWorkItem(DoSomeThing, 5);3 4 //用任務來做相同的事情5 Task.Run(() => DoSomeThing(5));
二 任務拋出異常
如果計算限制的任務拋出未處理的異常,異常會被"吞噬"並儲存到一個集合中,
而線程池線程可以返回到線程池中.調用Wait方法或者Result屬性時,這些成員
會拋出一個System.AggregateException對象.
三 取消任務
調用CancellationToken的ThrowIfCancellationRequested,如果CancellationToken
已經取消,任務將會拋出OperationCanceledException.之所以選擇拋出異常,是因為
和ThreadPool的QueueUserWorkItem方法初始化的工作項目不同,任務有辦法表示完成,
任務甚至能返回一個值.所以,採取一種方式將已完成的任務和出錯的任務區分開.
而讓任務拋出異常,就可以知道任務沒有一直運行到結束.
1 CancellationTokenSource cts = new CancellationTokenSource(); 2 Task<int> t = Task.Run<int>(() => Sum(cts.Token, 2000)); 3 Thread.Sleep(10); 4 cts.Cancel(); 5 6 try 7 { 8 Console.WriteLine("The Sum is: " + t.Result); 9 }10 catch (AggregateException x)11 {12 //將任何OperationCanceledException對象都視為已處理13 //使其中只包含未處理的異常14 x.Handle(e => e is OperationCanceledException);15 16 //對未處理的異常進行處理17 //TODO18 //...19 //...20 21 Console.WriteLine("Sum was canceled");22 }
1 static int Sum(CancellationToken ct,int n) 2 { 3 if (n > 1000) 4 { 5 throw new Exception("Value of n is too large."); 6 } 7 8 int sum = 0; 9 for (int i = 1; i <= n; i++)10 {11 //如果CancellationTokenSource已取消(Cancel),12 //下面代碼將拋出"System.OperationCanceledException"異常13 ct.ThrowIfCancellationRequested();14 sum += i;15 }16 return sum;17 }
四 Parallel的靜態For,ForEach和Invoke方法
使用Parallel的方法一些前提條件:
a.工作項目必須能並存執行,如果工作必須順序執行,就不要使用Paralle方法;
b.工作項目最好不要有修改共用資料的操作,否則多個線程同時處理共用資料,可能會算壞
資料;
c.每個工作項目都涉及大量工作,那麼使用Parallel方法產生的效能損失可以忽略不計;
d.有大量可由多個線程同時處理的工作項目,那麼使用Parallel也許能獲得效能的提升.
1 //Parallel的For方法 2 for (int i = 0; i < 1000; i++) 3 { 4 DoWork(i); 5 } 6 Parallel.For(0, 1000, i => DoWork(i)); 7 8 //Parallel的ForEach方法 9 int[] idCollection = new int[] {1,2,3,4,5,6,7,8,9 };10 foreach (var item in idCollection)11 {12 DoWork(item);13 }14 Parallel.ForEach(idCollection, item => DoWork(item));15 16 //Parallel的Invoke方法17 Method1();18 Method2();19 Method3();20 Parallel.Invoke(21 () => Method1(),22 () => Method2(),23 () => Method3());
五 定時計算限制操作(Timer)
FCL提供了幾個以下幾種主要的定時器:
a.System.Threading的Timer類
要在一個線程池上執行定時的(周期性發生的)背景工作,它是最好的計時器.
b.System.Timers的Timer類
這個計時器本質上是System.Threading的Timer類的封裝類,它允許在Visual
Studio中的設計器更容易使用.
建議不用這個計時器,除非真的想在設計平面上添加一個計時器.
c.System.Windows.Forms的Timer類
(CLR via C#學習筆記)任務和並行操作