未处理的异常下一行或退出

时间:2012-10-04 15:52:05

标签: c# visual-studio-2012 unhandled-exception

[更新2:问题已解决,请参阅下面的评论和我的其他帖子。希望这有助于某人。]

[更新:作为此问题基础的我对其他问题Detecting Exceptions During Beta Testing的回复存在缺陷。在Visual Studio中,无论是2010年还是现在,2012年都很棒。调用异常处理程序,好吧VS在该行中断后我说要继续。我决定在VS2012 IDE之外进行测试,对此有好处。操作系统捕获错误,显示标准“发生未处理的异常”对话框,提供详细信息以及继续和退出按钮。选择continue,只需继续应用程序,不会陷入我的超级异常处理程序。选择相当,白色的应用程序并显示标准关闭窗口对话框。退出按钮也不会调用我的超级处理程序。

目的是调用我的异常处理程序。如果我在VS2012 IDE中工作,我不需要一个超级异常处理程序。处理程序的目的是为最终用户和beta测试人员,即除了我自己以外的任何人都没有我的开发站。

以下代码在IDE外部无效。因此,Close App和Continue这两个按钮毫无意义,因为永远不会调用异常处理程序。在IDE下运行并使用代码(为什么这不是浪费我的时间?),继续不会继续,退出不会退出。我一遍又一遍地看到同样的例外。是的,我正在发布可能的答案。

我真的认为这个主题会很好用并通过.Net 4.5解决。 ]

我添加了一个未处理的异常处理程序,它与我的主表单不同,我在Application.Run(new frmMain())调用之前添加了它。处理程序按预期工作,没有问题。

问题: 1.是否有可能,如果是这样,强行关闭/结束违规表格(基本上是关闭应用程序)?

我在主窗体上添加了一个按钮,在OnClick事件中,我只是将其除以零,以便巧妙地模拟坏事。我正在运行VS2012调试环境。当然,我首先击中了VS指责我的违规行,但是在继续执行时,我点击了未处理的异常处理程序。在该处理程序中,一个选项是结束执行。我执行了“Application.Exit()”,但没有效果。我一直回到那条冒犯线上。

  1. 是否可以从异常处理程序以编程方式从下一行继续执行?
  2. 简单地回来只是让我回到那一点。

    我已经知道了try / catch块,但是这里的目的是捕获我未预料到的未处理的异常,并且在最坏的情况下,我可以发送一个有意义的崩溃报告,我从该处理程序生成。

    JMK要求提供一些示例代码,但不确定这会带来什么。

    我抛出一个对话框来响应未处理的异常。有4个按钮,两个用于此发布的目的。第一个按钮允许用户继续,而第二个按钮终止应用程序。至少,这就是想法。

            private void cmdContinue_Click(object sender, EventArgs e)
        {
            // Close this dialog and attempt to resume.
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
    
        private void cmdExitApp_Click(object sender, EventArgs e)
        {
            // Close this dialog and attempt to resume.
            this.DialogResult = DialogResult.OK;
            this.Close();
    
            // Exit the application.
            Application.Exit();
        }
    

    至少在VS2012 IDE中,continue块仅保留在违规行。退出街区同样如此。

    就我的例外情况而言,例外可以是任何事情。这就是我写它的原因。我的专用例外仅仅是测试代码,然后按钮再见。我正在努力创造一个完美的非破坏性的应用程序,但是这个目标是虚幻的,直到那个时候这个块。此机制的另一个目的是让测试人员向我报告错误。

    这是我的超快速和脏的未处理异常的代码。我不得不变得棘手,因为简单地除以零会被编译器捕获。顺便说一句,未处理的异常通常不会出现在我编写的特定行上,而是出现在方法内部对其他人的代码的调用中。

            private void button1_Click(object sender, EventArgs e)
        {
            // Attempt to throw and unhandled exception to test out the unhandled exception handler.
            int iDivider = 0;
            int iResult = 5 / iDivider;
        }
    

    这是另一个代码块,即测试应用程序的启动。

            public static frmMain FormMain = null;
    
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            // 
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
    
            // Turn on global unhandled exception handling.
            cExceptions.Initialize();
    
            // Run the application load tasks manually, as Windows will not call this event until the show.
            Program.FormMain = new frmMain();
    
            Application.Run(Program.FormMain);
        }
    

    有人要求我的异常处理程序,所以在这里。基本上,微软提供了样本。

        /// <summary>
    /// Based on example at http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
    /// </summary>
    internal static class cExceptions
    {
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        public static void Initialize()
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
        }
    
        static void MyHandler(object sender, UnhandledExceptionEventArgs args)
        {
            Exception ex = (Exception)args.ExceptionObject;
    
    
            // Log the exception to disk.
    
            // Show the exception information to the user.
            using (frmExceptions oException = new frmExceptions())
            {
                // Set the exeption information.
                oException.oEx = ex;
    
                // Show the dialog.
                oException.ShowDialog();
            }
    
            Console.WriteLine("MyHandler caught : " + ex.Message);
        }
    }
    

    提前致谢。

2 个答案:

答案 0 :(得分:2)

在Application.Run之前,继续引用类范围内的new frmMain())(即字段)。在Exception处理程序中使用它来调用frm.Close();

编辑:在第二次阅读时,看起来您不想关闭应用;而是抛出异常的形式。

在你的处理程序中,将“object sender”强制转换为表单然后你应该可以关闭它。 如下所示:

private void Exception_hander(object sender, EventArgs e) 
{ 
    if (sender is Form) 
    {
      ((Form)sender).Close();
    }
    else 
     { 
       ((Control)sender).Parent.Close();
     }
 } 

答案 1 :(得分:0)

好的,Google Uberlord对我很不满意,我找到了解决这个问题的精彩文章。赞美全能的谷歌。

这是链接: http://www.switchonthecode.com/tutorials/csharp-tutorial-dealing-with-unhandled-exceptions

基本上,JRadness有正确的想法,只是略有错误。他本应该用

Application.ThreadException += 
    new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

而不是

AppDomain.CurrentDomain.UnhandledException += 
    new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Switch on the Code上的作者谈到了三种方法,第一种是JRadness提出的方法,不适用于Windows表单。

autor甚至解决了我继续和中止的另一个问题。操作系统被绕过了。这是他的事件处理程序。

public static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    DialogResult result = DialogResult.Abort;
    try
    {
        Exception ex = (Exception)e.Exception;
        MessageBox.Show("Whoops! Please contact the developers with the"
             + " following information:\n\n" + e.Exception.Message + e.Exception.StackTrace,
             "Application Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
    }
    finally
    {
        if (result == DialogResult.Abort)
        {
            Application.Exit();
        }
    }
}

呀!