我可以向聯播AppDomain.CurrentDomain.UnhandledException
記錄從後臺線程的例外,但如何防止他們終止運行時?如何防止後臺線程中的異常終止應用程序?
回答
首先,你真的應該儘量避免在後臺線程中拋出異常並且不處理異常。如果你控制你的委託經營的方式,將其封裝在一個try catch塊和(使用EndInvoke會,如果你顯式調用的BeginInvoke,或更新某個地方某個共享狀態)計算的方式來傳遞異常信息返回到你的主線程。
忽略一個未處理的異常可能是危險的。如果你有一個真正的不可處理的異常(OutOfMemoryException記住),那麼你無法做任何事情,你的過程基本上是註定要失敗的。
返回到.NET 1.1,在backgroundthread未處理的異常也只是拋出無處和主線程會樂意犁上。這可能會帶來討厭的影響。所以在.Net 2.0中,這種行爲已經改變。現在
,未處理的異常在一個線程這不是主線程將終止該進程拋出。您可能會收到此通知(通過訂閱AppDomain上的事件),但該流程將會終止。
由於這可能不方便(當您不知道線程中將運行什麼,並且您不確定是否有適當的防護措施並且您的主線程必須具有彈性)時,有一種解決方法。它的目的是作爲一個傳統的設置(這意味着,強烈建議你確保你沒有雜散的線程),但你可以用這種方式強制以前的行爲:
只需將此設置添加到您的服務/應用程序/任何配置文件:
<configuration>
<runtime>
<!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>
它似乎並不與ASP.NET的工作,雖然。
欲瞭解更多信息(和一個巨大的警告,這種設置可能無法在CLR的未來版本將支持)看到http://msdn.microsoft.com/en-us/library/ms228965.aspx
從喬阿爾巴哈利的優秀threading文章:
.NET Framework提供了全局異常 處理一個 較低級別的事件: AppDomain.UnhandledException。此 事件觸發時,有未處理 例外在任何線程中,並且在任何 類型的應用程序(具有或不具有 用戶界面)。然而,儘管 提供了一個良好的最後手段機制 用於記錄未捕獲的例外,它 提供防止關閉 應用程序沒有辦法 - 和 絕非打壓.NET 未處理的異常對話框。
在生產應用程序中,所有 線程輸入方法都需要明確的 異常處理。人們可以通過使用包裝或輔助 類來執行該作業切割 工作,如 BackgroundWorker的(在 第3部分討論)。
這裏是一個偉大的博客文章對這個問題:Handling "Unhandled Exceptions" in .NET 2.0
IMO它會手動處理後臺線程中的異常並在必要時通過回調重新拋出它們是正確的。
delegate void ExceptionCallback(Exception ex);
void MyExceptionCallback(Exception ex)
{
throw ex; // Handle/re-throw if necessary
}
void BackgroundThreadProc(Object obj)
{
try
{
throw new Exception();
}
catch (Exception ex)
{
this.BeginInvoke(new ExceptionCallback(MyExceptionCallback), ex);
}
}
private void Test()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(BackgroundThreadProc));
}
保持答案的簡短,是的,你可以防止運行時終止。
下面是解決方法的演示:
class Program
{
void Run()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("Press enter to exit.");
do
{
(new Thread(delegate()
{
throw new ArgumentException("ha-ha");
})).Start();
} while (Console.ReadLine().Trim().ToLowerInvariant() == "x");
Console.WriteLine("last good-bye");
}
int r = 0;
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Interlocked.Increment(ref r);
Console.WriteLine("handled. {0}", r);
Console.WriteLine("Terminating " + e.IsTerminating.ToString());
Thread.CurrentThread.IsBackground = true;
Thread.CurrentThread.Name = "Dead thread";
while (true)
Thread.Sleep(TimeSpan.FromHours(1));
//Process.GetCurrentProcess().Kill();
}
static void Main(string[] args)
{
Console.WriteLine("...");
(new Program()).Run();
}
}
從本質上講,你只是沒有讓運行時顯示「...程序已停止工作」的對話。
如果您需要登錄異常,並默默退出,你可以叫Process.GetCurrentProcess().Kill();
AppDomain.CurrentDomain.UnhandledException += (sender, e2) =>
{
Thread.CurrentThread.Join();
};
但是要小心,這個代碼將凍結線程和線程的管理對象自身的所有堆棧存儲器。 但是,如果您的應用程序處於確定狀態(可能是您拋出了LimitedDemoFunctionalityException或OperationStopWithUserMessageException),並且您沒有開發全天候應用程序,則此技巧將起作用。
最後,我認爲MS應該允許開發人員從棧頂重寫未處理異常的邏輯。
- 1. 如何防止並行線程中的異常終止應用程序?
- 2. 如何防止node.js應用程序終止在setInterval中未處理的異常?
- 3. 如何防止由於應用程序終止而中止線程?
- 4. C#線程異常終止異常
- 5. 如何在iphone中終止應用程序後運行後臺線程?
- 6. 異常終止程序?
- 7. WPF中的線程異常終止
- 8. 如何防止Android應用程序因後臺線程中的IOException而崩潰?
- 9. 如何防止由於後臺線程中的異常導致android應用程序崩潰?
- 10. 如何防止殺死/終止或停止Windows應用程序
- 11. 防止終止控制檯應用程序
- 12. 線程不在delphi的控制檯應用程序中終止?
- 13. Java - Eclipse IDE,由指針異常終止程序終止程序
- 14. 如何在WebSphere下停止應用程序的後臺線程
- 15. 應用程序安裝程序異常進程終止(android)
- 16. 防止未處理的異常停止應用程序
- 17. 在未處理的異常後終止應用程序
- 18. 線程應用程序意外終止
- 19. iOS應用程序在UITableViewDataSource方法拋出異常後終止
- 20. Grails應用程序在發生異常後終止
- 21. PHP線程腳本異常終止
- 22. 防止用戶終止Java程序?
- 23. Application.Exit()是否會終止後臺線程?
- 24. 當Asp.net終止後臺線程?
- 25. 如何防止異常停止我的程序?
- 26. 阻止程序終止的線程
- 27. 如何處理異常並防止崩潰應用程序
- 28. 如何確定應用程序是在後臺還是終止?
- 29. 防止控制檯應用程序在捕獲異常後關閉
- 30. Unix的後臺進程異常停止
有嘗試...趕上各地的臭味。我只想在未處理的位置只需要一個,並且不希望我的應用程序因爲用戶去點擊「功能X」時發生的簡單的空指針而死亡,並且我們告訴他們使用正在工作的其他功能X按鈕。 。它並沒有關閉應用程序,每次都會讓用戶感到懊惱,就像原來的bug一樣惱火(引導應用程序需要時間,因此會給用戶帶來麻煩) – 2011-12-30 18:31:54
我遇到了有問題的專有外部庫它會使用(內部)`ArgumentNullException`異常地崩潰應用程序。我想爲那個庫啓用`legacyUnhandledExceptionPolicy`。這可以做到嗎? – chris 2015-05-14 11:15:46