亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ESBasic 可復(fù)用的.NET類庫(04) -- 循環(huán)引擎

系統(tǒng) 1811 0
1. 緣起:

有些系統(tǒng)需要每隔一段時間就執(zhí)行一下某個動作,比如,一個監(jiān)控系統(tǒng)每隔 10 秒鐘就要檢測一下被監(jiān)控對象的狀態(tài)是否正常,那這時我們就可以用到循環(huán)引擎了。

有人說可以使用 .NET 框架自帶定時器如 System.Threading.Timer ,嗯,沒錯。但是若這個類使用不當(dāng)可能會引發(fā)后臺池線程耗盡的后果。因為 Timer 的定時事件觸發(fā)實在后臺線程池中的某個線程中處理的。也就是說 Timer 的每次定時事件觸發(fā)都會用到一個線程,如果定時的時間間隔小于事件處理的時間,則后臺線程池中將會有越來越多的線程被 Timer 使用掉,直至線程池中再無空閑的線程。

ESBasic.Threading.Engines.ICycleEngine 的設(shè)計目標是永遠都只使用一個線程。比如,它會隔 10 秒執(zhí)行一個 Action ,執(zhí)行完后再隔 10 秒再執(zhí)行 Action 。間隔時間的等待與 Action 的執(zhí)行都是在同一個線程中處理的。
循環(huán)引擎的形象示意圖如下:

ESBasic 可復(fù)用的.NET類庫(04) -- 循環(huán)引擎 ICycleEngine

2.
適用場合:

根據(jù)上面的描述你應(yīng)該已經(jīng)看到了 ICycleEngine Timer 之間的區(qū)別。由于 Action 的執(zhí)行會占用額外的時間,所以 ICycleEngine 不適合于精確定時的任務(wù)。比如上面的例子,下一個 Action 開始的時刻與上一個 Action 開始的時刻的真正的時間差可能是 12 秒,而不是 10 秒,因為上一個 Action 的執(zhí)行花費了 2 秒。

所以,如果你的系統(tǒng)不需要精確的定時任務(wù),而且又不想花費過多的精力去防范使用 Timer 時線程耗盡的窘境出現(xiàn),那么 ICycleEngine 將是個不錯的選擇。

3 .設(shè)計思想與實現(xiàn)

ICycleEngine 接口的源碼如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> /// <summary>
/// ICycleEngine在后臺線程中進行間隔循環(huán)的引擎
/// zhuweisky2006.12.21
/// </summary>
public interface ICycleEngine
{
/// <summary>
/// Start啟動后臺引擎線程
/// </summary>
void Start();

/// <summary>
/// Stop停止后臺引擎線程,只有當(dāng)線程安全退出后,該方法才返回
/// </summary>
void Stop();

/// <summary>
/// IsRunning引擎是否運行中
/// </summary>
bool IsRunning{ get ;}

/// <summary>
/// DetectSpanInSecs引擎進行輪詢的間隔,DetectSpanInSecs=0,表示無間隙運作引擎;DetectSpanInSecs小于0則表示不使用引擎
/// </summary>
int DetectSpanInSecs{ get ; set ;}

/// <summary>
/// OnEngineStopped當(dāng)引擎由運行變?yōu)橥V範顟B(tài)時,將觸發(fā)此事件。如果是異常停止,則事件參數(shù)為異常對象,否則,事件參數(shù)為null。
/// </summary>
event CbExceptionOnEngineStopped;
}


如何實現(xiàn)這個接口了?

由于不同的系統(tǒng)要求執(zhí)行的 Action 不一樣,所以,我們可以實現(xiàn)一個 abstract 基類 BaseCycleEngine 來保證循環(huán)引擎的正常運轉(zhuǎn),而派生類只要 override 基類的 abstract 方法 DoDetect 來執(zhí)行自己的 Action

關(guān)于 BaseCycleEngine 的實現(xiàn)要注意以下幾點:

(1) 循環(huán)引擎是在后臺線程池的某個線程上運行的。

(2) 循環(huán)引擎可以無限次的啟動、停止、啟動、停止 ……

(3) 為了保證調(diào)用 Stop 方法時能迅速地停止引擎,我將間隔時間劃分為多個 BaseCycleEngine.SleepTime 。而不是一次性地 Sleep 間隔時間。

(4) 為了保證循環(huán)引擎真正停止后,才返回 Stop 方法的調(diào)用,我使用了 ManualResetEvent 來進行控制。

(5) DoDetect 方法的返回值為 false ,則表示在該 Action 執(zhí)行完后將停止循環(huán)引擎。此后,可以重新調(diào)用 Start 方法再次啟動循環(huán)引擎。

4. 使用時的注意事項

(1) 要確保我們的 Action (即派生類的 DoDetect 方法)不任何拋出異常,否則會導(dǎo)致循環(huán)引擎異常停止,并導(dǎo)致循環(huán)引擎的內(nèi)部狀態(tài)損壞而不可用。所以在派生類的 DoDetect 方法方法實現(xiàn)時捕捉所有的異常并加以處理。

(2) DoDetect 方法實現(xiàn)中不能調(diào)用 Stop 方法,否則會導(dǎo)致死鎖出現(xiàn)。

(3) 如果將 DetectSpanInSecs 設(shè)為 0 ,則表示無間隙的執(zhí)行 DoDetect 方法。而如果將 DetectSpanInSecs 設(shè)為負數(shù),則表示不啟動循環(huán)引擎。

(4) 當(dāng)引擎已經(jīng)啟動并正在運行的過程中,如果要改變 DetectSpanInSecs 的值并使其生效,則必須重新啟動(先調(diào)用 Stop 方法再調(diào)用 Start 方法)引擎才可。

5. 擴展

1 AgileCycleEngine

在上面的介紹中,我們都是以 DoDetect 方法來表示要執(zhí)行的 Action ,而且我們必須以繼承 BaseCycleEngine 的方式來使用循環(huán)引擎,這無疑限制了循環(huán)引擎的使用。

AgileCycleEngine 的存在便是為了突破這個限制。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public sealed class AgileCycleEngine : BaseCycleEngine
{
private IEngineActorengineActor;

public AgileCycleEngine(IEngineActor_engineActor)
{
this .engineActor = _engineActor;
}

protected override bool DoDetect()
{
return this .engineActor.EngineAction();
}
}


AgileCycleEngine 繼承自 BaseCycleEngine ,但是它是非 abstract 的。 AgileCycleEngine 通過組合而非繼承的方式來使用循環(huán)引擎,我們可以將 Action 的執(zhí)行者抽象為一個接口 IEngineActor

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public interface IEngineActor
{
/// <summary>
/// EngineAction執(zhí)行引擎動作,返回false表示停止引擎。
/// 注意,該方法不能拋出異常,否則會導(dǎo)致引擎停止運行(循環(huán)線程遭遇異常退出)。
/// </summary>
bool EngineAction();
}

通過實現(xiàn) IEngineActor 來表明我們要執(zhí)行的 Action ,然后將其注入到 AgileCycleEngine 中。

2 )永不停止的循環(huán)引擎

我們再考慮一個擴展的情況,假設(shè)我們的系統(tǒng)要求在啟動時就將引擎運行起來,而且在整個運行的生命周期中,都不需要停止引擎,那么我們可能不想將 Start 方法、 Stop 方法暴露出來以免意外的調(diào)用 Stop 方法而導(dǎo)致引擎停止運行,那這個時候我們可以使用類似下面的技巧來做到:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public sealed class MyCircleEngine : IEngineActor
{
private AgileCycleEngine agileCycleEngine;
public void Initialize()
{
this .agileCycleEngine = new AgileCycleEngine( this );
this .agileCycleEngine.DetectSpanInSecs = 10 ;
this .agileCycleEngine.Start();
}
#region IEngineActor成員
public bool EngineAction()
{
// MyAction
return true ;
}
#endregion
}

用于示例的 MyCycleEngine 內(nèi)部使用了 AgileCycleEngine ,但它沒有暴露循環(huán)引擎的任何控制方法,而且 Initialize 方法表明 MyCycleEngine 只要一初始化便開始運行,而且沒有辦法讓其停止運行。 MyCycleEngine 實現(xiàn)了 IEngineActor 接口,并把自己注入到 AgileCycleEngine 類型的成員中,于是引擎將每隔 10 秒鐘執(zhí)行一次 MyCycleEngine EngineAction 方法。

注:ESBasic源碼可到 http://esbasic.codeplex.com/ 下載。
ESBasic討論:37677395
ESBasic開源前言

ESBasic 可復(fù)用的.NET類庫(04) -- 循環(huán)引擎 ICycleEngine


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲成在人色婷婷 | 日本狠狠干 | 国产一级视频播放 | 看真人一级毛多毛片 | 国产大片中文字幕在线观看 | 奇米影视久久777中文字幕 | 激情五月婷婷基地 | 久久久这里只有免费精品2018 | 91视频大全 | 色综合久久综合网欧美综合网 | 香蕉爱视频 | 在线播放福利 | 亚洲欧洲日韩在线 | 麻豆精品永久免费视频 | 一区二区3区免费视频 | 天堂成人精品视频在线观 | 免费观看成人久久网免费观看 | 中文字幕日韩在线观看 | 久久这里有精品视频任我鲁 | 久久国产视频在线观看 | 天天爽天天摸 | 国产精品麻豆高清在线观看 | 日韩综合nv一区二区在线观看 | 亚洲综合色视频 | 在线视频一区二区三区四区 | 日韩欧美视频一区二区在线观看 | 精品久久一区二区三区 | 亚洲精品免费日日日夜夜夜夜 | 久久99国产精品免费观看 | 成人免费视频在 | 97桃色| 狼狼色丁香久久婷婷综合五月 | 久久国产精彩视频 | 国产一区二区高清在线 | 午夜体验区 | 国产综合久久久久久 | 久久久香蕉视频 | 亚洲成a人片在线观看www | 可以免费观看的毛片 | 国产成人精品久久一区二区三区 | 中文字幕伦理聚合第一页 |