您好,登錄后才能下訂單哦!
本篇內容介紹了“.Net如何使用Cancellation Framework取消并行任務”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在.net 4.0中,引入了一個新的類CancellationToken,這個類基本上集成了我們各種常用的取消方式,在并發任務中非常有用。
一種比較常見的需要支持取消功能的的是一些比較耗時的分段操作:如視頻轉換,網絡下載等,這種方式下的取消機制如下:
建立一個標記位,表示該操作是否已經取消
UI線程在獲取到取消事件后,置標記位為true
耗時的操作線程里,沒進行一小段操作之后查詢該標記位,如果為true則主動退出。
使用方式如下:
EventHandler externalEvent; void Example1() { CancellationTokenSource cts = new CancellationTokenSource(); externalEvent += (sender, obj) => { cts.Cancel(); }; //wire up an external requester try { int val = LongRunningFunc(cts.Token); } catch (OperationCanceledException) { //cleanup after cancellation if required... } } private static int LongRunningFunc(CancellationToken token) { int total = 0; for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) { total++; } if (token.IsCancellationRequested) { // observe cancellation throw new OperationCanceledException(token); // acknowledge cancellation } } return total; }
另外一種常見的方式是在一些異步操作中,往往不能主動釋放,只能等待異步操作回調的時候才能操作結果。此時一般取消方法如下:
任務線程注冊異步操作完成的回調函數,開始異步操作。
UI線程接受取消指令,置取消標記位,并主動執行回調函數
回調函數中通過取消標記位判斷該任務是已經完成還是被取消的,并執行相關析構操作。
使用方式如下:
void BlockingOperation(CancellationToken token) { ManualResetEvent mre = new ManualResetEvent(false); //register a callback that will set the MRE CancellationTokenRegistration registration = token.Register(() => mre.Set()); using (registration) { mre.WaitOne(); if (token.IsCancellationRequested) //did cancellation wake us? throw new OperationCanceledException(token); } //dispose the registration, which performs the deregisteration. }
這里我們通過CancellationToken注冊了一個回調方法以通知任務等待線程,也可以以我們經常使用的WaitHandle的那樣的方式使用。
void Wait(WaitHandle wh, CancellationToken token) { WaitHandle.WaitAny(new[] { wh, token.WaitHandle }); if (token.IsCancellationRequested) //did cancellation wake us? throw new OperationCanceledException(token); }
由于例子比較簡單,這里就只列舉一下代碼,不多介紹了。
一個CancellationToken對應多個任務
void Example4() { CancellationTokenSource cts = new CancellationTokenSource(); Func1(cts.Token); Func2(cts.Token); Func3(cts.Token); //... cts.Cancel(); // all listeners see the same cancellation request. }
一個任務對應多個CancellationToken
void LinkingExample(CancellationToken ct1, CancellationToken ct2) { CancellationTokenSource linkedCTS = CancellationTokenSource.CreateLinkedTokenSource(ct1, ct2); try { SlowFunc(linkedCTS.Token); } catch (OperationCanceledException oce) { if (ct1.IsCancellationRequested) { // ... } else if (ct2.IsCancellationRequested) { // ... } } linkedCTS.Dispose(); // clean up the linking. required. }
最后我們再來一個并發查詢時取消的例子:
private void RunQuery() { int[] data = { 1, 2, 3 }; CancellationTokenSource cts = new CancellationTokenSource(); var query = data.AsParallel() .WithCancellation(cts.Token) // token given to library code .Select((x) => SlowFunc(x, cts.Token)); // token passed to user code } private int SlowFunc(int x, CancellationToken token) { int result while(...) { if (token.IsCancellationRequested) throw new OperationCanceledException(token); ... } return result; }
“.Net如何使用Cancellation Framework取消并行任務”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。