【问题标题】:Unhandled Exception next line or exit未处理的异常下一行或退出
【发布时间】:2012-10-04 15:52:05
【问题描述】:

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

[更新:对我的另一个问题Detecting Exceptions During Beta Testing 的回答是这个问题的基础有缺陷。在 Visual Studio 中,2010 和现在的 2012 都运行良好。异常处理程序被调用,好吧,在 VS 换行后我说继续。我决定在 VS2012 IDE 之外进行测试,这是一件好事。操作系统捕获错误,显示标准的“发生未处理的异常”对话框,提供详细信息以及继续和退出按钮。选择继续,只是继续应用程序而不陷入我的超级异常处理程序。选择相当,白化应用程序并显示标准关闭窗口对话框。退出按钮也不会调用我的超级处理程序。

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

下面的代码在 IDE 之外不起作用。因此,关闭应用程序和继续这两个按钮毫无意义,因为异常处理程序永远不会被调用。在 IDE 下运行并使用代码时(为什么这不是浪费我的时间?), continue 不会继续,exit 不会退出。我只是一遍又一遍地看到同样的异常。是的,我正在尝试发布的可能答案。

我真的认为这个话题会很好地用 .Net 4.5 解决。 ]

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

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

我在主窗体上添加了一个按钮,在 OnClick 事件中,我只是简单地除以零,以便有针对性地模拟一些不好的东西。我正在使用 VS2012 调试环境运行。自然,我首先点击了 VS 提醒我的违规行,但是在继续执行时,我点击了未处理的异常处理程序。在该处理程序中,一种选择是结束执行。我执行了“Application.Exit()”,但没有效果。我一直回到那条令人讨厌的路线。

  1. 是否可以通过异常处理程序以编程方式从下一行继续执行?

简单地返回就可以让我回到那个点。

我已经知道 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();
    }

continue 块,至少在 VS2012 IDE 中,只是保持在有问题的行。退出块也是如此。

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

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

        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);
    }
}

提前致谢。

【问题讨论】:

  • 你能添加一些你的代码吗?展示你正在尝试做的事情可能比仅仅解释更清楚
  • 我修改了帖子并给出了一些代码。
  • 您可以复制粘贴我在处理程序示例上发布的内容。按原样复制“if..else”块并将其放在 ShowDialog() 之后。

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


【解决方案1】:

在 Application.Run 之前将 new frmMain()) 的引用保留在类范围内(即字段)。在异常处理程序中使用它来调用 frm.Close();

编辑:在第二次阅读时,您似乎不想关闭应用程序;而是抛出异常的表单。

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

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

【讨论】:

  • 我确实想关闭应用程序,您的想法很棒,就在我的 VS2012 IDE 会话中,不行。可悲的是,cmets 不是多行代码或允许代码。在 cmdExitApp_Click(sender, e) 事件处理程序中,我添加了一行(在 Application.Exit() 之前)“Program.FormMain.Close()”。我仍然有同样的行为,永远坐在违规线上。按钮的发送者是我未处理的异常对话框,它没有父级。
  • 您必须发布您的异常处理程序代码。它应该可以工作。
  • 好的,异常处理程序已添加到原始帖子的底部。一个对话框就是一个对话框,一个对话框就是一个对话框,为此我给了按钮点击事件处理程序。
  • 仅供参考,您可以通过使用 as 然后检查 null 来避免转换两次。 Form form = sender as Form; if (form != null) form.Close();
  • else 子句导致编译器错误:“System.Windows.Forms.Control”不包含“Close”的定义,并且没有扩展方法“Close”接受类型的第一个参数...此外,将发件人的关闭移动到外部,同样的问题也不起作用。 :-( 在 IDE 之外执行,最重要的是,不会导致异常处理程序触发,只是 os 一个。
【解决方案2】:

好的,Google Uberlord 对我很失望,我发现这篇精彩的文章解决了这个问题。向全能的 Google 致敬。

这里是链接: 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 窗体。

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

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();
        }
    }
}

是啊!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多