網站首頁 編程語言 正文
在.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 4.0中的Cancellation Framework還是非常實用的,通過它可以更有效的簡化及規范的使用各種取消的操作方式,由于我也只會皮毛,在這里也只是介紹了它的基本用法,在后續的學習和應用中將繼續進一步介紹。
原文鏈接:https://www.cnblogs.com/TianFang/archive/2009/11/04/1596197.html
相關推薦
- 2023-05-26 Pycharm直接使用遠程服務器代碼并調試的解決方法_python
- 2023-12-13 SpringMVC——訪問action報404錯誤詳解
- 2022-06-30 python神經網絡ResNet50模型的復現詳解_python
- 2022-08-26 C++超集C++/CLI模塊的基本類型_C 語言
- 2022-04-26 jQuery實現鎖定頁面元素(表格列)_jquery
- 2022-12-29 python解決循環依賴的問題分析_python
- 2022-03-26 .NET?6中使用DateOnly和TimeOnly類型_ASP.NET
- 2022-05-10 .NET實現異步編程async和await_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支