我已經實現了一個具有DLL庫的軟件,其中包含一大類包含我軟件所有方法的類。WinForms全局異常處理?
現在我想能夠處理一些全局錯誤,如錯誤#26這是所有這些類上沒有網絡相關錯誤,而不是去每個類,並添加它。怎麼做 ?
我已經實現了一個具有DLL庫的軟件,其中包含一大類包含我軟件所有方法的類。WinForms全局異常處理?
現在我想能夠處理一些全局錯誤,如錯誤#26這是所有這些類上沒有網絡相關錯誤,而不是去每個類,並添加它。怎麼做 ?
如果#26
是例外,那麼您可以使用AppDomain.CurrentDomain.UnhandledException
事件。如果它只是一個回報值,那麼我認爲沒有機會在全球範圍內處理這個問題。
由於它是一個winforms應用程序,您可以將Application.Run(new MainForm());
放在try catch塊中。
static void Main()
{
try {
Application.Run(new MainForm());
} catch(SystemException)//just as an example
{
//log or handle the error here.
}
}
我不知道這種解決方案會造成什麼影響,但我只是告訴過你需要什麼。其他選項訂閱Application.ThreadException事件。
更多在這裏閱讀:unhandledexceptions
還有AppDomain.UnhandledException,你應該閱讀here on MSDN之間的區別。
從MSDN:
對於某些應用模型中,UnhandledException事件可以由其他事件,如果在主應用程序線程中發生未處理的異常搶佔。
在使用Windows窗體的應用程序中,主應用程序線程中的未處理的異常導致引發Application.ThreadException事件。如果處理此事件,則默認行爲是未處理的異常不會終止應用程序,儘管應用程序仍處於未知狀態。在這種情況下,不會引發UnhandledException事件。此行爲可以通過使用應用程序配置文件進行更改,或者在ThreadException事件處理程序掛鉤之前使用Application.SetUnhandledExceptionMode方法將模式更改爲UnhandledExceptionMode.ThrowException。這僅適用於主應用程序線程。 UnhandledException事件是針對在其他線程中拋出的未處理的異常引發的。
由於上面顯示的延伸,我使用以下命令:
try
{
Application.Run(new FormMain());
}
catch (Exception ex)
{
RoboReporterConstsAndUtils.HandleException(ex);
}
...其中HandleException()方法可以是這樣的:
internal static void HandleException(Exception ex)
{
var exDetail = String.Format(ExceptionFormatString,
ex.Message,
Environment.NewLine,
ex.Source,
ex.StackTrace,
ex.InnerException);
ExceptionLoggingService.Instance.LogAndEmailExceptionData(string.Format("{0}: {1}: {2}",
DateTime.Now.ToLongDateString(), GetVersionInfo(), exDetail));
}
另一種方式對皮膚這個貓是:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppDomain.CurrentDomain.UnhandledException += Unhandled;
Application.Run(new FormMain());
}
static void Unhandled(object sender, UnhandledExceptionEventArgs exArgs)
{
ExceptionLoggingService.Instance.LogAndEmailMessage(String.Format
("From application-wide exception handler: {0}", exArgs.ExceptionObject));
}
當然,你可以在Unhandled()方法中做任何你想做的事情。
隨着Centralized Exception Handling在C#Windows應用程序的參考,我發現了很好的解決方案之一:
static class Program
{
[STAThread]
static void Main()
{
// Add handler to handle the exception raised by main threads
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
// Add handler to handle the exception raised by additional threads
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
// Stop the application and all the threads in suspended state.
Environment.Exit(-1);
}
static void Application_ThreadException
(object sender, System.Threading.ThreadExceptionEventArgs e)
{// All exceptions thrown by the main thread are handled over this method
ShowExceptionDetails(e.Exception);
}
static void CurrentDomain_UnhandledException
(object sender, UnhandledExceptionEventArgs e)
{// All exceptions thrown by additional threads are handled in this method
ShowExceptionDetails(e.ExceptionObject as Exception);
// Suspend the current thread for now to stop the exception from throwing.
Thread.CurrentThread.Suspend();
}
static void ShowExceptionDetails(Exception Ex)
{
// Do logging of exception details
MessageBox.Show(Ex.Message, Ex.TargetSite.ToString(),
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
在上面的類,我們將附上一個事件處理兩個事件。一旦主要方法啓動,最好附加這些事件。
Application.ThreadException - 在主線程中引發異常時會引發此事件。如果我們添加一個事件處理程序,那麼通過該方法處理異常。
AppDomain.CurrentDomain.UnhandledException - 當一個異常在應用程序中使用額外的線程將引發此事件將得到提升。這裏情況越糟糕,只要處理程序的執行結束,異常再次拋出,而應用程序結束。這需要處理。在這裏,我使用了一些代碼來處理這種情況,並繼續執行應用程序而不中斷。
我用來克服這種情況的邏輯只是暫停事件處理程序中的線程,以便應用程序繼續正常工作。在暫停此線程中再次出現問題。當主窗體關閉時,應用程序通常需要退出,但由於線程處於暫停狀態,應用程序仍將保持運行狀態。因此,要完全退出應用程序並停止該過程,必須在主方法結束之前調用Environment.Exit(-1)。
首先,你應該加上:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
之後,你可以捕獲異常,例如:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += ApplicationThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
if (DataBaseMNG.Init())
{
Application.Run(new MainForm());
}
}
/// <summary>
/// Global exceptions in Non User Interfarce(other thread) antipicated error
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var message =
String.Format(
"Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.",
((Exception)e.ExceptionObject).Message, ((Exception)e.ExceptionObject).StackTrace);
MessageBox.Show(message, @"Unexpected error");
}
/// <summary>
/// Global exceptions in User Interfarce antipicated error
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
{
var message =
String.Format(
"Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.",
e.Exception.Message, e.Exception.StackTrace);
MessageBox.Show(message, @"Unexpected error");
}
如果把這段代碼,如果您有任何引用,或者你可以發佈一個例子,我會很滿。 – ykh
請參閱我答案中的MSDN鏈接。它有一個例子:http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – gideon