我似乎不能正确地说明我应该如何正确处理意外的异常。
考虑以下应用程序:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SomeForm());
}
class SomeForm : Form
{
public SomeForm()
{
Button btn = new Button();
btn.Text = "Click ME";
btn.Location = new System.Drawing.Point(20, 20);
btn.Click += new EventHandler(btn_Click);
Controls.Add(btn);
}
void btn_Click(object sender, EventArgs e)
{
throw new Exception("This is an Exception");
}
}
如果我运行此应用程序并单击按钮,我会得到一个未处理的异常。起初我尝试使用try catch块围绕Application.Run,如下所示:
try { Application.Run(new SomeForm()); }
catch { MessageBox.Show("Exception caught in try catch"); }
起初这似乎有效,直到我在调试器外部运行应用程序。在调试器外部运行应用程序时,异常将报告为未处理的错误。在做了一些阅读之后,我发现我应该查看Application.ThreadException事件。所以我做了以下几点:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
try { Application.Run(new SomeForm()); }
catch { MessageBox.Show("Exception caught in try catch"); }
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception caught in event");
}
现在,当我在调试器外部运行我的应用程序时,会处理异常并且MessageBox指示它已在事件处理程序中捕获。然后我回到调试器并运行它。现在调试器将它作为未处理的异常启动,即使我已经在try catch中包围它并且我绑定到Application.ThreadException事件。如果我没有绑定到Application.ThreadException事件,那么try catch块会正确捕获异常。
现在回答问题:
答案 0 :(得分:3)
您可以使用AppDomain.CurrentDomain.UnhandledException
和Application.ThreadException
,look for more来处理它们。
答案 1 :(得分:3)
调试器将传播到Application_ThreadException的异常视为未处理的异常,因为该事件处理程序用作正常记录和终止的最终位置。这允许您在运行调试器时停止在异常点,这通常非常有用。
在一个全局位置处理所有异常是不可能的,因为没有足够的上下文来知道如何实际处理它们。您可以使用Application_ThreadException(以及其他线程上的异常的AppDomain.UnhandledException)捕获所有异常(甚至是未处理的异常),但在这种情况下您应该做的下一步是关闭您的应用程序。
您应该根据您拥有的信息以及可能发生的异常类型的知识,分别处理每种方法中的异常。不应该捕获您不知道如何处理的异常,并且将渗透到“全局”事件处理程序,这些处理程序应记录详细信息并礼貌地关闭应用程序。