C# WinForms全局异常处理?
我实现了一个软件,它有一个DLL库,其中包含一组庞大的类,其中包括我的软件的所有方法C# WinForms全局异常处理?,c#,winforms,C#,Winforms,我实现了一个软件,它有一个DLL库,其中包含一组庞大的类,其中包括我的软件的所有方法 现在我希望能够处理一些全局错误,比如error#26,这是所有这些类上的一个与网络无关的错误,而不是去每个类并添加它。如何做到这一点?因为它是一个winforms应用程序,所以您可以将Application.Run(new MainForm())封装起来在try-catch块中 static void Main() { try { Application.Run(new MainForm()); } catc
现在我希望能够处理一些全局错误,比如error#26,这是所有这些类上的一个与网络无关的错误,而不是去每个类并添加它。如何做到这一点?因为它是一个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.
}
}
我不知道这种解决方案会带来什么影响,但我只是告诉你你需要什么
其他选项是订阅事件
请在此处阅读更多信息:
还有AppDomain.UnhandledException,您应该了解它们之间的区别
从MSDN:
对于某些应用程序模型,如果未处理的异常发生在主应用程序线程中,则未处理的异常事件可以被其他事件抢占
在使用Windows窗体的应用程序中,主应用程序线程中未处理的异常会导致引发application.ThreadException事件。如果处理了此事件,默认行为是未处理的异常不会终止应用程序,尽管应用程序处于未知状态。在这种情况下,不会引发UnhandledException事件。在连接ThreadException事件处理程序之前,可以使用应用程序配置文件,或使用application.SetUnhandledExceptionMode方法将模式更改为UnhandledExceptionMode.ThroweException来更改此行为。这仅适用于主应用程序线程。对于在其他线程中引发的未处理异常,将引发UnhandledException事件
处理事件。如果#26
是异常,则可以使用AppDomain.CurrentDomain.UnhandledException
事件。如果它只是一个返回值,那么我看不出有任何机会全局处理它
publicstaticvoidmain()
{
AppDomain.CurrentDomain.UnhandledException+=新的UnhandledExceptionEventHandler(MyHandler);
//从这里开始主线程
}
静态void MyHandler(对象发送方,未处理的ExceptionEventArgs参数)
{
异常e=(异常)args.ExceptionObject;
Console.WriteLine(“MyHandler捕获:+e.Message”);
}
作为上述内容的扩展,我使用以下内容:
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()方法中,您可以做任何您想做的事情。参考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;
Application.Run(new MainForm());
}
/// <summary>
/// Global exceptions in Non User Interface (other thread) handler
/// </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 Interface handler
/// </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");
}
[STAThread]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException+=ApplicationThreadException;
AppDomain.CurrentDomain.UnhandledException+=CurrentDomainOnUnhandledException;
运行(新的MainForm());
}
///
///非用户界面(其他线程)处理程序中的全局异常
///
///
///
私有静态void CurrentDomainOnUnhandledException(对象发送方,UnhandledExceptionEventArgs e)
{
var消息=
字符串格式(
“抱歉,出现问题。\r\n”+“{0}\r\n”+“{1}\r\n”+“请与支持部门联系。”,
((异常)e.ExceptionObject).Message,((异常)e.ExceptionObject.StackTrace);
MessageBox.Show(消息,@“意外错误”);
}
///
///用户界面处理程序中的全局异常
///
///
///
私有静态无效应用程序ReadException(对象发送方,ThreadExceptionEventArgs e)
{
var消息=
字符串格式(
“抱歉,出现问题。\r\n”+“{0}\r\n”+“{1}\r\n”+“请与支持部门联系。”,
e、 异常。消息,例如异常。堆栈跟踪);
MessageBox.Show(消息,@“意外错误”);
}
winforms中的全局错误拦截
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new myForm());
}
catch (Exception ex)
{
HandleException(ex);
}
}
internal static void HandleException(Exception ex)
{
string LF = Environment.NewLine + Environment.NewLine;
string title = $"Oups... I got a crash at {DateTime.Now}";
string infos = $"Please take a screenshot of this message\n\r\n\r" +
$"Message : {LF}{ex.Message}{LF}" +
$"Source : {LF}{ex.Source}{LF}" +
$"Stack : {LF}{ex.StackTrace}{LF}" +
$"InnerException : {ex.InnerException}";
MessageBox.Show(infos, title, MessageBoxButtons.OK, MessageBoxIcon.Error); // Do logging of exception details
}
}
静态类程序
{
///
///应用程序的主要入口点。
///
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
尝试
{
运行(新的myForm());
}
捕获(例外情况除外)
{
手部异常(ex);
}
}
内部静态无效句柄异常(异常