詳解C#如何為某個方法設(shè)定執(zhí)行超時時間
C# 給某個方法設(shè)定執(zhí)行超時時間在某些情況下(例如通過網(wǎng)絡(luò)訪問數(shù)據(jù)),常常不希望程序卡住而占用太多時間以至于造成界面假死。
在這時、我們可以通過Thread、Thread + Invoke(UI)或者是 delegate.BeginInvoke 來避免界面假死,
但是這樣做時,某些代碼或者是某個方法的執(zhí)行超時的時間還是無法操控的。那么我們又是否有一種比較通用的方法、來設(shè)定某一個方法的執(zhí)行超時的時間,讓其一旦超過指定時間則跳出指定方法、進(jìn)而繼續(xù)向下執(zhí)行呢?
答案當(dāng)然是肯定的。
delegate.BeginInvoke可以實現(xiàn)代碼代碼的異步執(zhí)行,在這種情況下,只要讓程序可以等待一個Timespan,如果在Timespan到達(dá)之前方法內(nèi)的代碼還沒有執(zhí)行完畢、說明該方法執(zhí)行超時了。
那么關(guān)鍵的就是“等待一個Timespan”,而恰好.NET 里提供了一些類和方法來實現(xiàn)該功能。我這里選用的是ManualResetEvent.WaitOne(timespan, false);其返回值代碼其是否在特定時間內(nèi)收到信號,而我們恰好可以利用這個布爾值 外加一個標(biāo)記變量 來判斷一個方法是否執(zhí)行超時。
相關(guān)的實現(xiàn)代碼如下:
publicdelegatevoid DoHandler(); publicclass Timeout { private ManualResetEvent mTimeoutObject; //標(biāo)記變量 privatebool mBoTimeout; public DoHandler Do; public Timeout() { // 初始狀態(tài)為 停止 this.mTimeoutObject =new ManualResetEvent(true); } ///<summary> /// 指定超時時間 異步執(zhí)行某個方法 ///</summary> ///<returns>執(zhí)行 是否超時</returns> publicbool DoWithTimeout(TimeSpan timeSpan) { if (this.Do ==null) { returnfalse; } this.mTimeoutObject.Reset(); this.mBoTimeout =true; //標(biāo)記 this.Do.BeginInvoke(DoAsyncCallBack, null); // 等待 信號Set if (!this.mTimeoutObject.WaitOne(timeSpan, false)) { this.mBoTimeout =true; } returnthis.mBoTimeout; } ///<summary> /// 異步委托 回調(diào)函數(shù) ///</summary> ///<param name="result"></param> privatevoid DoAsyncCallBack(IAsyncResult result) { try { this.Do.EndInvoke(result); // 指示方法的執(zhí)行未超時 this.mBoTimeout =false; } catch (Exception ex) { Console.WriteLine(ex.Message); this.mBoTimeout =true; } finally { this.mTimeoutObject.Set(); } } }
測試代碼如下:
class Program { privatestatic Stopwatch watch; privatestatic System.Threading.Timer timer; [STAThread] staticvoid Main(string[] args) { watch =new Stopwatch(); Timeout timeout =new Timeout(); timeout.Do =new Program().DoSomething; watch.Start(); timer =new System.Threading.Timer(timerCallBack, null, 0, 500); Console.WriteLine("4秒超時開始執(zhí)行"); bool bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 4)); Console.WriteLine(string.Format("4秒超時執(zhí)行結(jié)果,是否超時:{0}", bo)); Console.WriteLine("***************************************************"); timeout =new Timeout(); timeout.Do =new Program().DoSomething; Console.WriteLine("6秒超時開始執(zhí)行"); bo = timeout.DoWithTimeout(new TimeSpan(0, 0, 0, 6)); Console.WriteLine(string.Format("6秒超時執(zhí)行結(jié)果,是否超時:{0}", bo)); timerCallBack(null); watch.Stop(); timer.Dispose(); Console.ReadLine(); } staticvoid timerCallBack(object obj) { Console.WriteLine(string.Format("運行時間:{0}秒", watch.Elapsed.TotalSeconds.ToString("F2"))); } publicvoid DoSomething() { // 休眠 5秒 System.Threading.Thread.Sleep(new TimeSpan(0, 0, 0, 5)); } }
由上可得知:設(shè)定超時時間為4秒執(zhí)行方法 DoSomething,執(zhí)行結(jié)果為超時,并且在4秒后跳出方法DoSomething繼續(xù)向下執(zhí)行。
到此這篇關(guān)于詳解C#如何為某個方法設(shè)定執(zhí)行超時時間的文章就介紹到這了,更多相關(guān)C#設(shè)定執(zhí)行超時時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)對數(shù)組進(jìn)行隨機(jī)排序類實例
這篇文章主要介紹了C#實現(xiàn)對數(shù)組進(jìn)行隨機(jī)排序類,實例分析了C#數(shù)組與隨機(jī)數(shù)操作技巧,非常具有實用價值,需要的朋友可以參考下2015-03-03C#執(zhí)行存儲過程并將結(jié)果填充到GridView的方法
這篇文章主要介紹了C#執(zhí)行存儲過程并將結(jié)果填充到GridView的方法,結(jié)合實例形式分析了C#存儲過程操作及GridView控件相關(guān)操作技巧,需要的朋友可以參考下2017-02-02解析C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范
這篇文章主要介紹了C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范,這里我們根據(jù)C#語言的開發(fā)方微軟給出的約定來作為編寫樣式參照,需要的朋友可以參考下2016-01-01C#開發(fā)之int與string轉(zhuǎn)化操作
這篇文章主要介紹了C#開發(fā)之int與string轉(zhuǎn)化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12