網(wǎng)站首頁 編程語言 正文
在.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)一步介紹。
原文鏈接:https://www.cnblogs.com/TianFang/archive/2009/11/04/1596197.html
相關(guān)推薦
- 2024-01-06 關(guān)于class.getClassLoader().getResourceAsStream()和cla
- 2022-08-15 使用enum關(guān)鍵字定義的枚舉類實(shí)現(xiàn)接口的情況
- 2022-06-06 詳細(xì)講解Docker虛擬化_docker
- 2022-05-21 redis數(shù)據(jù)一致性的實(shí)現(xiàn)示例_Redis
- 2022-08-11 python中@Property屬性使用方法_python
- 2022-06-30 python神經(jīng)網(wǎng)絡(luò)MobileNetV2模型的復(fù)現(xiàn)詳解_python
- 2022-08-29 .NET?Core項(xiàng)目使用swagger開發(fā)組件_實(shí)用技巧
- 2022-08-27 C#實(shí)現(xiàn)截圖幫助類_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支