Den*_*nis 9 c# exception-handling winforms
我遇到过这样的情况.WinForms应用程序有两种形式.主窗体有一个按钮,当用户点击它时,会显示模态对话框.对话框表单也有一个按钮,当用户点击它时,抛出异常.
当应用程序在调试器下运行并运行时,异常处理会有所不同.这是最小的代码,重现这种行为:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
using (var dialog = new Form2())
{
dialog.ShowDialog();
}
}
catch (Exception ex)
{
MessageBox.Show("Oops! " + ex.Message);
}
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
调试时,引发异常会关闭对话框,Form1.button1_Click中的异常处理程序会处理异常.
在运行应用程序本身时,引发异常不会关闭对话框.而不是这样,默认调用Application.ThreadException处理程序.
为什么(以及为什么)行为有所不同?如何使它相互一致?
在Program.Main()中尝试这个:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
Application.Run(new Form1());
}
Run Code Online (Sandbox Code Playgroud)
原因是Windows Forms程序集在Visual Studio Hosting进程之外运行的方式.看到这个:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
如果将上面的代码行设置为:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Run Code Online (Sandbox Code Playgroud)
并在VS中运行它,您将看到默认行为是什么 - 一旦您跨过代码中的初始异常,将显示您引用的对话框.根据您是以托管模式还是独立模式运行,默认值会有所不同.
好吧,"为什么"在MS链接中有所涉及 - 错误发生在事件处理程序中,该处理程序位于不同的线程上.默认行为是仅在WinForms下对待它.如果在调用对话框后放置此行:
throw new Exception("Bah!");
Run Code Online (Sandbox Code Playgroud)
并保持CatchException上的行为,您将看到它如您所期望的那样转到您的异常处理程序.它只是事件处理程序中的异常,它以不同的方式处理.希望有所帮助.
归档时间: |
|
查看次数: |
2163 次 |
最近记录: |