异常处理多种形式 [英] Exception handling with multiple forms

查看:124
本文介绍了异常处理多种形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到的时候我调试与当我运行一个编译的.exe被抓与被抓还是不例外不同的行为。我有两种形式(Form 1和Form)。 Form1上上有一个按钮,实例化和窗体2调用ShowDialog的。窗体2上有一个按钮,按零错误,故意产生鸿沟。当我调试,在Form1中catch块被击中。当我运行编译的.exe,它不是打,而是我得到指出,发生在应用程序中未处理的异常的消息框。如果单击继续,应用程序将忽略此错误并尝试继续操作。如果您点击退出,应用程序将立即关闭......试图除以零。我的问题是,为什么在运行.exe文件时,调试与当你得到不同的行为?如果这是预期的行为,那么将它认为有必要把try / catch块,在每一个事件处理程序?这似乎是一种疯狂的超必杀,不是吗?



下面是Form1的代码。

 公共部分Form1类:表格
{
公共Form1中()
{
的InitializeComponent();

}

私人无效的button1_Click(对象发件人,EventArgs五)
{

{
窗体2 F2 =新Form2的();
f2.ShowDialog();
}
赶上(异常前)
{
MessageBox.Show(eX.ToString()); //此行仅调试
}
}
}



时,按

下面的窗体2的代码:

 公共部分类窗体2:表
{
公共窗体2()
{
的InitializeComponent();
}

私人无效的button1_Click(对象发件人,EventArgs五)
{
INT X = 0;
INT Y = 7 / X;

}
}


解决方案

我得到相同的行为你。我不知道为什么会这样,但它似乎是一个坏主意假设的形式从事件产生了一个异常会出现的ShowDialog()调用的堆栈。这将是更好地做这两件事情:




  • 捕获和处理在Form2的事件处理程序在有意义这样做例外,当你可以做一些有意义的事情除外。
  • 为您的整个应用程序捕捉任何未处理的异常添加未处理的异常处理程序(`Application_ThreadException`)。


更​​新:这里是堆栈跟踪。 Debug版本:

  System.DivideByZeroException:试图除以零。在WindowsFormsApplication1.Form2.button1_Click(对象发件人,EventArgs e)在... \WindowsFormsApplication1\Form2.cs 
:第27行
在System.Windows.Forms.Control.OnClick(EventArgs的发送)
在System.Windows.Forms.Button.OnClick(EventArgs五)
在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在System.Windows.Forms.Control.WmMouseUp (消息和M,MouseButtons按钮,点击的Int32)在System.Windows.Forms.Control.WndProc(消息和M)

在System.Windows.Forms.ButtonBase.WndProc(消息和M)
。在System.Windows.Forms.Button.WndProc(消息和M)在System.Windows.Forms.Control.ControlNativeWindow.OnMessage
(消息和M)
在System.Windows.Forms的。 Control.ControlNativeWindow.WndProc(消息和M)在System.Windows.Forms.NativeWindow.DebuggableCallback
(IntPtr的的HWND,味精的Int32,IntPtr的WPARAM,LPARAM的IntPtr)
在System.Windows.Forms.UnsafeNativeMethods。 DispatchMessageW(MSG&安培;味精)
在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(的Int32 dwComponentID,的Int32原因,的Int32 pvLoopData)在System.Windows
.Forms.Application.ThreadContext.RunMessageLoopInner(的Int32原因,ApplicationContext的情况下)
在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(的Int32原因,ApplicationContext的情况下)
在System.Windows.Forms.Application .RunDialog(表格形式)
在System.Windows.Forms.Form.ShowDialog(IWin32Window所有者)在System.Windows.Forms.Form.ShowDialog
()
在WindowsFormsApplication1.Form1.button1_Click (对象发件人,EventArgs e)在... \WindowsFormsApplication1\Form1.cs:45行

版本:

  System.DivideByZeroException:试图除以零。在WindowsFormsApplication1.Form2.button1_Click(对象发件人,EventArgs e)在... \WindowsFormsApplication1\Form2.cs 
:第27行
在System.Windows.Forms.Control.OnClick(EventArgs的发送)
在System.Windows.Forms.Button.OnClick(EventArgs五)
在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在System.Windows.Forms.Control.WmMouseUp (消息和M,MouseButtons按钮,点击的Int32)在System.Windows.Forms.Control.WndProc(消息和M)

在System.Windows.Forms.ButtonBase.WndProc(消息和M)
。在System.Windows.Forms.Button.WndProc(消息和M)在System.Windows.Forms.Control.ControlNativeWindow.OnMessage
(消息和M)
在System.Windows.Forms的。 Control.ControlNativeWindow.WndProc(消息和M)
在System.Windows.Forms.NativeWindow.Callback(IntPtr的的HWND,味精的Int32,IntPtr的WPARAM,LPARAM的IntPtr)

注意 System.Windows.Forms.Form.ShowDialog()是不是在释放的堆栈跟踪模式,这就是为什么你的尝试{}赶上{} 什么都不做。同样值得注意的是,在调试情况下,它是使用 NativeWindow.DebuggableCallback 这大概是旨在通过没有违反协议栈,以帮助调试,而在发布模式是使用 NativeWindow.Callback


I'm seeing different behavior with exceptions being caught or not being caught when I am debugging vs. when I am running a compiled .exe. I have two forms (Form1 and Form2). Form1 has a button on it which instantiates and calls ShowDialog on Form2. Form2 has a button on it which intentionally produces a divide by zero error. When I'm debugging, the catch block in Form1 is hit. When I run the compiled .exe, it is NOT hit, and instead I get a message box that states, "Unhandled exception has occurred in your application. If you click continue, the application will ignore this error and attempt to continue. If you click Quit, the application will close immediately...Attempted to divide by zero". My question is why do you get different behavior when debugging vs. when running the .exe? If that is the expected behavior, then would it be considered necessary to put try/catch blocks in every single event handler? That seems kind of crazy over kill, doesn't it?

Here's the code for Form1.

public partial class Form1 : Form
{
    public Form1()
    {
            InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }
        catch(Exception eX)
        {
            MessageBox.Show( eX.ToString()); //This line hit when debugging only
        }
    }
}

Here's Form2's code:

public partial class Form2 : Form
{
    public Form2()
    {
            InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
            int x = 0;
            int y = 7 / x;

    }
}

解决方案

I get the same behaviour as you. I don't know why this happens, but it seems to be a bad idea to assume that an exception generated from an event in a form will appear on the stack of the ShowDialog() call. It would be better to do these two things:

  • Catch and handle the exceptions in the event handlers in Form2 where it makes sense to do so, and when you can do something meaningful with the exception.
  • Add an unhandled exception handler (`Application_ThreadException`) for your entire application to catch any unhandled exceptions.

Update: Here are the stack traces. Debug version:

System.DivideByZeroException: Attempted to divide by zero.
   at WindowsFormsApplication1.Form2.button1_Click(Object sender, EventArgs e) in ...\WindowsFormsApplication1\Form2.cs:line 27
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.RunDialog(Form form)
   at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
   at System.Windows.Forms.Form.ShowDialog()
   at WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) in ...\WindowsFormsApplication1\Form1.cs:line 45

Release:

System.DivideByZeroException: Attempted to divide by zero.
   at WindowsFormsApplication1.Form2.button1_Click(Object sender, EventArgs e) in ...\WindowsFormsApplication1\Form2.cs:line 27
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Notice that System.Windows.Forms.Form.ShowDialog() is not in the stack trace in release mode, which is why your try {} catch {} does nothing. Also notable is that in the debug case it is using NativeWindow.DebuggableCallback which is presumably designed to help debugging by not breaking the stack, whereas in Release mode is uses NativeWindow.Callback.

这篇关于异常处理多种形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆