.Net使用Cancellation?Framework取消并行任務(wù)
在.net 4.0中,引入了一個(gè)新的類CancellationToken,這個(gè)類基本上集成了我們各種常用的取消方式,在并發(fā)任務(wù)中非常有用。
同步模式下的取消:
一種比較常見的需要支持取消功能的的是一些比較耗時(shí)的分段操作:如視頻轉(zhuǎn)換,網(wǎng)絡(luò)下載等,這種方式下的取消機(jī)制如下:
建立一個(gè)標(biāo)記位,表示該操作是否已經(jīng)取消
UI線程在獲取到取消事件后,置標(biāo)記位為true
耗時(shí)的操作線程里,沒進(jìn)行一小段操作之后查詢?cè)摌?biāo)記位,如果為true則主動(dòng)退出。
使用方式如下:
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; }
異步模式下的取消
另外一種常見的方式是在一些異步操作中,往往不能主動(dòng)釋放,只能等待異步操作回調(diào)的時(shí)候才能操作結(jié)果。此時(shí)一般取消方法如下:
任務(wù)線程注冊(cè)異步操作完成的回調(diào)函數(shù),開始異步操作。
UI線程接受取消指令,置取消標(biāo)記位,并主動(dòng)執(zhí)行回調(diào)函數(shù)
回調(diào)函數(shù)中通過(guò)取消標(biāo)記位判斷該任務(wù)是已經(jīng)完成還是被取消的,并執(zhí)行相關(guān)析構(gòu)操作。
使用方式如下:
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. }
這里我們通過(guò)CancellationToken注冊(cè)了一個(gè)回調(diào)方法以通知任務(wù)等待線程,也可以以我們經(jīng)常使用的WaitHandle的那樣的方式使用。
void Wait(WaitHandle wh, CancellationToken token) { WaitHandle.WaitAny(new[] { wh, token.WaitHandle }); if (token.IsCancellationRequested) //did cancellation wake us? throw new OperationCanceledException(token); }
高級(jí)應(yīng)用
由于例子比較簡(jiǎn)單,這里就只列舉一下代碼,不多介紹了。
一個(gè)CancellationToken對(duì)應(yīng)多個(gè)任務(wù)
void Example4() { CancellationTokenSource cts = new CancellationTokenSource(); Func1(cts.Token); Func2(cts.Token); Func3(cts.Token); //... cts.Cancel(); // all listeners see the same cancellation request. }
一個(gè)任務(wù)對(duì)應(yīng)多個(gè)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. }
最后我們?cè)賮?lái)一個(gè)并發(fā)查詢時(shí)取消的例子:
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; }
小結(jié)
.net 4.0中的Cancellation Framework還是非常實(shí)用的,通過(guò)它可以更有效的簡(jiǎn)化及規(guī)范的使用各種取消的操作方式,由于我也只會(huì)皮毛,在這里也只是介紹了它的基本用法,在后續(xù)的學(xué)習(xí)和應(yīng)用中將繼續(xù)進(jìn)一步介紹。
到此這篇關(guān)于.Net使用Cancellation Framework取消并行任務(wù)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解ASP.NET Core 處理 404 Not Found
這篇文章主要介紹了詳解ASP.NET Core 處理 404 Not Found,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10asp.net下URL網(wǎng)址重寫成.html格式、RSS、OPML的知識(shí)總結(jié)
asp.net下URL網(wǎng)址重寫成.html格式、RSS、OPML的知識(shí)總結(jié)...2007-09-09.NET下實(shí)現(xiàn)數(shù)字和字符相混合的驗(yàn)證碼實(shí)例
這篇文章介紹了.NET下實(shí)現(xiàn)數(shù)字和字符相混合的驗(yàn)證碼實(shí)例,有需要的朋友可以參考一下2013-11-11Asp.net實(shí)現(xiàn)直接在瀏覽器預(yù)覽Word、Excel、PDF、Txt文件(附源碼)
本文主要介紹了Asp.net實(shí)現(xiàn)直接在瀏覽器預(yù)覽Word、Excel、PDF、Txt文件的具體實(shí)例。文章篇尾附上源碼下載,有興趣的朋友可以看下2016-12-12ASP.NET中的URL過(guò)濾實(shí)現(xiàn)代碼
最近做的一個(gè)Web項(xiàng)目需要對(duì)URL進(jìn)行過(guò)濾,在網(wǎng)上搜了一下,知道J2EE有個(gè)Filter的東西,而在.NET方面,其實(shí)也可以實(shí)現(xiàn)2013-01-01.net c# gif動(dòng)畫如何添加圖片水印實(shí)現(xiàn)思路及代碼
本文將詳細(xì)介紹下c#實(shí)現(xiàn)gif動(dòng)畫添加圖片水印,思路很清晰,感興趣的你可以參考下哈,希望可以幫助到你2013-03-03