.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ù)中通過取消標(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.
}這里我們通過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è)賮硪粋€(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í)用的,通過它可以更有效的簡(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中DataTable與DataSet之間的轉(zhuǎn)換示例
如果你的數(shù)據(jù)不需要做關(guān)系映射,直接用DataTable效率比較高,下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以參考下2013-09-09
.Net Core創(chuàng)建Api進(jìn)行文件上傳功能
這篇文章主要介紹了.Net Core創(chuàng)建Api進(jìn)行文件上傳,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
ASP.net中網(wǎng)站訪問量統(tǒng)計(jì)方法代碼
這篇文章介紹了ASP.net中網(wǎng)站訪問量統(tǒng)計(jì)方法代碼,有需要的朋友可以參考一下2013-11-11
Asp.net使用SignalR實(shí)現(xiàn)酷炫端對(duì)端聊天功能
這篇文章主要為大家詳細(xì)介紹了Asp.net使用SignalR實(shí)現(xiàn)酷炫端對(duì)端聊天功能,感興趣的小伙伴們可以參考一下2016-04-04

