日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.Net Cancellable Task - APM异步超时机制扩展

發(fā)布時(shí)間:2025/3/15 asp.net 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Cancellable Task - APM异步超时机制扩展 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

概述

.NET基于委托的APM(Asynchronous Programming Model)模式通過(guò)BeginInvoke, EndInvoke, AsyncCallback,IAsyncResult的組合使用,讓程序員可以方便的進(jìn)行異步調(diào)用、異步回調(diào)和同步等待等操作。但.NET平臺(tái)還沒(méi)有為線(xiàn)程的中止(abort)提供安全可靠的機(jī)制,也許正是基于這個(gè)原因APM并沒(méi)有包含異步調(diào)用的超時(shí)機(jī)制,而是把這個(gè)可能引起爭(zhēng)議的工作交給使用者自己來(lái)把握。

作為APM模型的補(bǔ)充,本文通過(guò)CancellableTask類(lèi)提供了一個(gè)異步調(diào)用超時(shí)機(jī)制。CancellableTask類(lèi)的設(shè)計(jì)有兩個(gè)主要的考慮:

1.保持APM風(fēng)格,使用者依然可以使用熟悉的BeginInvoke, EndInvoke, IAsyncResult, AsyncCallback等;

2.提供基于Thread.Abort的默認(rèn)超時(shí)處理,同時(shí)支持用戶(hù)自定義cancel回調(diào)。

使用

CancellableTask的構(gòu)造函數(shù)包含workCallbak和cancelCallback(可選)兩參數(shù),分別對(duì)應(yīng)work回調(diào)和cancel回調(diào)。CancellableTask的BeginInvoke保持了APM的風(fēng)格,可以看作是增加了timeout參數(shù)(單位:ms)的擴(kuò)展版;而EndInvoke,AsyncCallback以及IAsyncResult的使用都和APM保持一致。Work委托產(chǎn)生的異常會(huì)在EndInvoke時(shí)拋出,同時(shí)若線(xiàn)程被超時(shí)中止,EndInvoke則會(huì)拋出ThreadAbortException異常。

下面是一段CancellableTask的使用示例:

?

class?Program
{
????
static?void?Main(string[]?args)
????{
????????
//默認(rèn)超時(shí)直接abort線(xiàn)程
????????{
????????????Console.WriteLine(
"[case?1]");

????????????CancellableTask?cancellableTask?
=?new?CancellableTask(Work);

????????????State?arg?
=?new?State?{?Loop?=?20,?Stop?=?false?};
????????????IAsyncResult?asyncResult?
=?cancellableTask.BeginInvoke(
????????????????arg,?
????????????????(ar?
=>?Console.WriteLine("Async?Callback")),?
????????????????
null,?
????????????????
10?*?1000);
????????????asyncResult.AsyncWaitHandle.WaitOne();
????????????
try
????????????{
????????????????
object?r?=?cancellableTask.EndInvoke(asyncResult);
????????????????Console.WriteLine(
"return?"?+?r);
????????????}
????????????
catch?(ThreadAbortException)
????????????{
????????????????Console.WriteLine(
"Thread?Aborted");
????????????}
????????????
catch?(Exception?exp)
????????????{
????????????????Console.WriteLine(exp.ToString());
????????????}
????????}

????????
//自定義Cancel回調(diào)
????????{
????????????Console.WriteLine(Environment.NewLine?
+?"[case?2]");

????????????CancellableTask?cancellableTask?
=?new?CancellableTask(Work,?Cancel);

????????????State?arg?
=?new?State?{?Loop?=?20,?Stop?=?false?};
????????????IAsyncResult?asyncResult?
=?cancellableTask.BeginInvoke(
????????????????arg,
????????????????(ar?
=>
????????????????????{
????????????????????????
try
????????????????????????{
????????????????????????????
object?r?=?cancellableTask.EndInvoke(ar);
????????????????????????????Console.WriteLine(
"return?"?+?r);
????????????????????????}
????????????????????????
catch?(ThreadAbortException)
????????????????????????{
????????????????????????????Console.WriteLine(
"Thread?Aborted");
????????????????????????}
????????????????????????
catch?(Exception?exp)
????????????????????????{
????????????????????????????Console.WriteLine(exp.ToString());
????????????????????????}
????????????????????}
????????????????),
????????????????arg,
????????????????
10?*?1000);
????????}
????????Console.ReadLine();
????}

????
static?object?Work(object?arg)
????{
????????State?state?
=?arg?as?State;
????????
int?i;
????????
for?(i?=?0;?i?<?state.Loop;?i++)
????????{
????????????
if?(state.Stop)?break;

????????????Console.WriteLine(i);
????????????Thread.Sleep(
1000);
????????}

????????
return?i;
????}

????
static?void?Cancel(object?state)
????{
????????State?st?
=?state?as?State;
????????st.Stop?
=?true;
????}
}

internal?class?State
{
????
public?int?Loop?{?get;?set;?}
????
public?bool?Stop?{?get;?set;?}
}

實(shí)現(xiàn)

CancellableTask通過(guò)wrapper對(duì)workCallback進(jìn)行包裝。Wrapper內(nèi)部首先創(chuàng)建等待事件e,并通過(guò)ThreadPool.RegisterWaitForSingleObject注冊(cè)事件和WaitOrTimeout回調(diào),然后調(diào)用workCallback。若workCallback提前返回,調(diào)用e.Set(),ThreadPool會(huì)調(diào)用WaitOrTimeout回調(diào),isTimeout參數(shù)為false,不進(jìn)行處理;否則,當(dāng)workCallback超時(shí)未返回,ThreadPool會(huì)調(diào)用WaitOrTimeout回調(diào),isTimeout參數(shù)為true。WaitOrTimeout回調(diào)在isTimeout情況下,首先判斷是否有自定義cancel回調(diào),如果有則采用自定義回調(diào);否則,默認(rèn)情況下調(diào)用Thread.Abort終止work線(xiàn)程。下面是CancellableTask的實(shí)現(xiàn)細(xì)節(jié):

?

public?class?CancellableTask
{
????
public?delegate?object?WorkCallback(object?arg);
????
public?delegate?void?CancelCallback(object?state);

????
protected?class?TimeoutState
????{
????????
internal?Thread?thread;
????????
internal?object?state;

????????
public?TimeoutState(Thread?thread,?object?state)
????????{
????????????
this.thread?=?thread;
????????????
this.state?=?state;
????????}
????}

????
protected?WorkCallback?workCallback;
????
protected?CancelCallback?cancelCallback;
????
protected?WorkCallback?wrapper;

????
public?CancellableTask(WorkCallback?workCallback)
????{
????????
this.workCallback?=?workCallback;
????}

????
public?CancellableTask(WorkCallback?workCallback,?CancelCallback?cancelCallback)
????{
????????
this.workCallback?=?workCallback;
????????
this.cancelCallback?=?cancelCallback;
????}

????
public?IAsyncResult?BeginInvoke(object?arg,?AsyncCallback?asyncCallback,?object?state,?int?timeout)
????{
????????wrapper?
=?delegate(object?argv)
????????{
????????????AutoResetEvent?e?
=?new?AutoResetEvent(false);

????????????
try
????????????{
????????????????TimeoutState?waitOrTimeoutState?
=?new?TimeoutState(Thread.CurrentThread,?state);

????????????????ThreadPool.RegisterWaitForSingleObject(e,?WaitOrTimeout,?waitOrTimeoutState,?timeout,?
true);

????????????????
return?workCallback(argv);
????????????}
????????????
finally
????????????{
????????????????e.Set();
????????????}
????????};

????????IAsyncResult?asyncResult?
=?wrapper.BeginInvoke(arg,?asyncCallback,?state);

????????
return?asyncResult;
????}

????
public?object?EndInvoke(IAsyncResult?result)
????{
????????
return?wrapper.EndInvoke(result);
????}

????
protected?void?WaitOrTimeout(object?state,?bool?isTimeout)
????{
????????
try
????????{
????????????
if?(isTimeout)
????????????{
????????????????TimeoutState?waitOrTimeoutState?
=?state?as?TimeoutState;

????????????????
if?(null?!=?cancelCallback)
????????????????{
????????????????????cancelCallback(waitOrTimeoutState.state);
????????????????}
????????????????
else
????????????????{
????????????????????waitOrTimeoutState.thread.Abort();
????????????????}
????????????}
????????}
????????
catch?{?}
????}
}

總結(jié)

本文為.NET APM模型提供了異步超時(shí)機(jī)制擴(kuò)展,一方面保持了APM編程風(fēng)格,另一方面支持用戶(hù)自定義cancel回調(diào)。需要注意的是,默認(rèn)的cancel方式Thread.Abort的安全性問(wèn)題,使用時(shí)應(yīng)注意資源釋放等。

作者

http://www.cnblogs.com/weidagang2046/,歡迎就線(xiàn)程問(wèn)題交流探討。

轉(zhuǎn)載于:https://www.cnblogs.com/weidagang2046/archive/2009/02/19/1394050.html

總結(jié)

以上是生活随笔為你收集整理的.Net Cancellable Task - APM异步超时机制扩展的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。