代码之家  ›  专栏  ›  技术社区  ›  PostMan

来自在MFC对话框中使用的托管C用户控件的未处理异常

  •  3
  • PostMan  · 技术社区  · 15 年前

    我们的核心应用程序是在MFC C++中构建的,但是我们正在尝试在.NET中编写新代码,并在.NET中创建了一个用户控件,该控件将在现有的MFC对话框中使用。

    但是,当从用户控件中引发意外/未处理的异常时,它会导致MFC应用程序崩溃(非法操作样式),无法恢复。

    我补充说

    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
    

    对于.NET用户控件的构造函数,但它似乎没有捕获任何内容。

    有没有办法在MFC中添加事件来处理这些问题?

    快速谷歌没有返回任何有用的信息。

    谢谢。


    编辑:仍然无法按我希望的方式解决这个问题,看起来像 最好的 实现这一点的方法是尝试捕获所有.NET代码,这样就不会出现异常。

    4 回复  |  直到 15 年前
        1
  •  3
  •   Community CDub    7 年前

    我刚才也问过这个问题: Final managed exception handler in a mixed native/managed executable?

    我发现,只有在托管线程中运行时才会触发托管未处理的异常事件。有管理的WndProc就是魔法发生的地方。

    您有几个选项:可以在cwinapp中放置一个低级重写,并捕获异常^。这可能会产生意想不到的副作用。或者,您可以使用结构化异常处理(SEH),它将为您提供一个hack at/all/unprocessed异常。这条路不容易走。

        2
  •  0
  •   Judah Gabriel Himango    15 年前

    我认为您希望在MFC方面有未处理的异常处理程序:

    appdomain::currentdomain->unhandledException+=gcnew unhandledExceptionEventHandler(&currentdomain_unhandledException);

    [应用程序相同。线程例外]

    在msdn论坛上看看这个类似的问题: Unhandled Exception in Mixed Mode application

        3
  •  0
  •   John Saunders    15 年前

    当然,更好的办法是要么处理C代码中的异常,要么找出导致异常的原因,然后修复它,这样就不会抛出异常。是什么阻止了这一切?

    在用户控件的每个事件处理程序中,放置一个try/catch块:

    private void btnOk_Click(object sender, EventArgs e) {
        try {
            // real code here
        }
        catch (Exception ex) {
            LogException(ex);
            // do whatever you must in order to shut down the control, maybe just
        }
    }
    

    我用的是:

    public static class UI
    {
        public static void PerformUIAction(Control form, Action action)
        {
            PerformUIAction(form, action, (string) null);
        }
    
        public static void PerformUIAction(
            Control form, Action action, string message)
        {
            PerformUIAction(form, action, () => message);
        }
    
        public static void PerformUIAction(
            Control form, Action action, Func<string> messageHandler)
        {
            var saveCursor = form.Cursor;
            form.Cursor = Cursors.WaitCursor;
            try
            {
                action();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    messageHandler() ?? ex.Message, "Exception!",
                    MessageBoxButtons.OK, MessageBoxIcon.Error,
                    MessageBoxDefaultButton.Button1,
                    MessageBoxOptions.DefaultDesktopOnly);
                Debug.WriteLine(ex.ToString(), "Exception");
                throw;
            }
            finally
            {
                form.Cursor = saveCursor;
            }
        }
    }
    

    我这样称呼它:

    private void _copyButton_Click(object sender, EventArgs e)
    {
        UI.PerformUIAction(
            this, () =>
                      {
                      // Your code here
                      });
    }
    
        4
  •  0
  •   Judah Gabriel Himango    15 年前

    我将未处理的异常处理程序添加到.NET用户控件的构造函数中

    我认为这不可行;我认为在调用application.run之前必须设置异常处理程序。你有什么应用程序吗?在你的应用程序中运行呼叫?

    在初始化任何.NET控件之前,在mfc端执行类似的操作如何:

    Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException);
    Application.ThreadException += ...;
    

    查看是否调用了ThreadException处理程序。