如何爲繁忙方法+ C#設置超時時間。如何設置方法的超時時間
回答
好的,這是真正的答案。
...
void LongRunningMethod(object monitorSync)
{
//do stuff
lock (monitorSync) {
Monitor.Pulse(monitorSync);
}
}
void ImpatientMethod() {
Action<object> longMethod = LongRunningMethod;
object monitorSync = new object();
bool timedOut;
lock (monitorSync) {
longMethod.BeginInvoke(monitorSync, null, null);
timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs
}
if (timedOut) {
// it timed out.
}
}
...
這結合了使用C#的兩個最有趣的部分。首先,要異步調用該方法,請使用具有花式魔術褲的代表。
然後,使用監視器將消息從LongRunningMethod
發送回ImpatientMethod
,以告知消息何時完成,或者是否在一定時間內未收到消息,請放棄。
(PS-只是開玩笑這是真正的答案。我知道有2^9303的方式皮膚貓,尤其是在.NET)
你不能這樣做,除非你改變方法。
有兩種方式:
- 的方法是建立在其本身的尺寸了多長時間運行的時間,如果超過某個閾值,然後返回過早這種方式。
- 該方法的構建方式是監視一個變量/事件,該變量說明「何時設置此變量,請退出」,然後您有另一個線程測量第一個方法花費的時間,然後設置當經過的時間超過某個閾值時變量。
最明顯的,但不幸的是,你可以在這裏得到的答案是「只要在線程中運行該方法,並在運行時間過長時使用Thread.Abort」。
唯一正確的方法是讓方法合作,以便在運行時間過長時進行乾淨的退出。
還有第三種方法,您可以在單獨的線程上執行該方法,但在等待完成後需要很長時間,您只需說「我不會等待它完成,但只是丟棄它「。在這種情況下,該方法仍然會運行,並最終完成,但等待它的其他線程將簡單放棄。
想想第三種方式叫某人,並要求他們在他們的房子裏搜索你借給他們的那本書,等到電話結束5分鐘後,你只需說出「aw,chuck it」,然後掛斷。最終,其他人會找到這本書,然後回到電話上,只是注意到你不再關心結果。
方法在C#中沒有超時,除非您在調試器或操作系統中認爲您的應用程序已「掛起」。即使這樣,處理仍然繼續,只要你不殺死應用程序,就會返回響應,應用程序繼續工作。
對數據庫的調用可能會超時。
您可以在單獨的線程中運行該方法,並對其進行監視,並在其過長時強制其退出。一種好的方法,如果你可以這樣稱呼它,那麼將爲Post Sharp中的方法開發一個屬性,這樣看守代碼就不會亂丟你的應用程序。
我已經寫了下面的示例代碼(注意,示例代碼的一部分,它的工作原理,但可以從多線程遭受的問題,或者如果有問題的方法捕獲的ThreadAbortException會打破它):
static void ActualMethodWrapper(Action method, Action callBackMethod)
{
try
{
method.Invoke();
} catch (ThreadAbortException)
{
Console.WriteLine("Method aborted early");
} finally
{
callBackMethod.Invoke();
}
}
static void CallTimedOutMethod(Action method, Action callBackMethod, int milliseconds)
{
new Thread(new ThreadStart(() =>
{
Thread actionThread = new Thread(new ThreadStart(() =>
{
ActualMethodWrapper(method, callBackMethod);
}));
actionThread.Start();
Thread.Sleep(milliseconds);
if (actionThread.IsAlive) actionThread.Abort();
})).Start();
}
以下調用:
CallTimedOutMethod(() =>
{
Console.WriteLine("In method");
Thread.Sleep(2000);
Console.WriteLine("Method done");
},() =>
{
Console.WriteLine("In CallBackMethod");
}, 1000);
我需要在我的代碼可讀性上工作。
您仍然需要編寫代碼添加到方法做一個乾淨的出口時,它要完成。 – 2009-09-11 12:49:00
你的意思是像抓住ThreadAbort異常和清理資源/提供退出代碼?這真的取決於所討論的方法。 – 2009-09-11 13:06:20
如果通過「超時」,他的意思是「我想關閉我的程序,不要等待方法完成」,那麼是的,可以使用Thread.Abort,但這是唯一的場景。 – 2009-09-11 13:44:01
您可以創建一個Asynchronous Method,以便您可以在「繁忙」方法完成時繼續執行其他任務嗎?
雖然MojoFilter's answer是很好,如果「它可能導致泄漏LongMethod「凍結。如果您對結果不再感興趣,您應該停止操作。
public void LongMethod()
{
//do stuff
}
public void ImpatientMethod()
{
Action longMethod = LongMethod; //use Func if you need a return value
ManualResetEvent mre = new ManualResetEvent(false);
Thread actionThread = new Thread(new ThreadStart(() =>
{
var iar = longMethod.BeginInvoke(null, null);
longMethod.EndInvoke(iar); //always call endinvoke
mre.Set();
}));
actionThread.Start();
mre.WaitOne(30000); // waiting 30 secs (or less)
if (actionThread.IsAlive) actionThread.Abort();
}
我經常編寫應用程序,必須跨平臺同步時間關鍵型任務。如果你可以避免thread.abort,你應該。有關thread.abort何時適用的指導,請參閱http://blogs.msdn.com/b/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx和http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation。下面是我實現的概念:
- 選擇性執行:只有當一個合理的成功機會存在(基於滿足超時或相對於其他排隊的項目成功結果的可能性的能力)上運行。如果將代碼分解爲段並大致瞭解任務塊之間的預期時間,則可以預測是否應該跳過任何進一步處理。總時間可以通過用時間計算遞歸函數包裝對象倉任務來測量,或者通過讓控制器類監視工作人員知道預期的等待時間來測量。
- 選擇性孤兒:如果存在合理的成功機會,請等待回報。索引的任務在受管隊列中運行。超過其超時或導致其他超時風險的任務將被孤立,並返回空記錄。長時間運行的任務可以包裝在異步調用中。請參閱示例異步調用封裝器:http://www.vbusers.com/codecsharp/codeget.asp?ThreadID=67&PostID=1
- 有條件選擇:類似於選擇性執行,但基於組而不是單個任務。如果許多任務互相連接,以至於一次成功或失敗都會導致其他處理無關緊要,請創建一個在開始執行前檢查的標誌,並在長時間運行的子任務開始前再次執行檢查。當你使用parallel.for或其他這樣的排隊併發任務時,這是特別有用的。
這是一個老問題,但它有一個更簡單的解決方案,現在不可用:任務!
這裏是一個示例代碼:
var task = Task.Run(() => LongRunningMethod());//you can pass parameters to the method as well
if (task.Wait(TimeSpan.FromSeconds(30)))
return task.Result; //the method returns elegantly
else
throw new TimeoutException();//the method timed-out
- 1. 如何設置Socket.ConnectAsync的超時時間?
- 2. 如何設置ProxyAgent的超時時間?
- 3. 如何設置OCILogon2的超時時間?
- 4. Libtorrent如何設置超時時間?
- 5. 如何爲PhantomJS設置超時時間?
- 6. 如何使用方法「CreateSqlStringAccessor」時設置「超時」?
- 7. 如何使用geo.js設置查找位置的超時時間?
- 8. 如何正確設置聯合ADFS 2.0時的超時時間
- 9. 設置tweepy的超時時間
- 10. 設置查詢的超時時間
- 11. 設置加載appcache的超時時間?
- 12. 設置java.net.URLConnection的最大超時時間
- 13. 爲請求方法設置超時
- 14. 在Ldap搜索設置方法超時
- 15. android - 如何設置超時
- 16. 如何設置ajax超時?
- 17. 如何設置IHttpAsyncHandler超時?
- 18. CLGeocoder如何設置超時?
- 19. 如何設置NHibernate的LINQ語句的超時時間
- 20. 如何在python的套接字recv方法上設置超時?
- 21. 動態設置超時時間
- 22. 爲NetworkObject.MapNetworkDrive設置超時時間
- 23. tokuDb設置時間以超時語句
- 24. iOS:Firebase存儲設置超時時間
- 25. 在org.apache.commons.io.FileUtils.copyURLToFile上設置超時時間?
- 26. 設置時間會話超時
- 27. 設置會話超時時間
- 28. 在simple_html_dom中設置超時時間
- 29. ZBar iPhone,設置超時時間
- 30. 在jQuery上設置超時時間.load
這對我有用:) – 2013-09-11 10:55:37
它確實有效,但!請注意! - 當執行流程返回時,「LongRunningMethod」仍然在後臺運行!這可能是泄漏。 – Alex 2013-09-29 21:34:01
這是完全正確的。如果你想停止等待一個動作,而不是停止一個動作,這是很好的。 – MojoFilter 2013-10-03 19:48:15