C# WindowsMobile:应用程序在处理DialogForm中的异常后退出

C# WindowsMobile:应用程序在处理DialogForm中的异常后退出,c#,winforms,exception,windows-mobile,C#,Winforms,Exception,Windows Mobile,我有以下简单的场景: 在带有按钮的DialogForm中,单击按钮会引发异常 带有按钮和标签的MainForm,在click I中,在Catch块内显示DialogForm的新实例 如果我在常规WinForms中运行此设置,我可以按预期捕获异常 如果我在WinMobile中运行它(我已经在WM5和WM6 Pro上测试过),我可以通过调试器看到Catch块被输入,但异常继续传播,应用程序死亡 MainForm中的代码如下所示: try { using (DialogForm frm = ne

我有以下简单的场景:

在带有按钮的DialogForm中,单击按钮会引发异常

带有按钮和标签的MainForm,在click I中,在Catch块内显示DialogForm的新实例

如果我在常规WinForms中运行此设置,我可以按预期捕获异常

如果我在WinMobile中运行它(我已经在WM5和WM6 Pro上测试过),我可以通过调试器看到Catch块被输入,但异常继续传播,应用程序死亡

MainForm中的代码如下所示:

try
{
   using (DialogForm frm = new DialogForm())
   {
     DialogResult r = frm.ShowDialog();
     label1.Text = r.ToString();
  }
}
catch (Exception ex)
{
  label1.Text = ex.Message;
}
编辑: 我进一步研究了一下,在这段代码和Application.Run()周围有一个catch{}块,应用程序仍然退出


显然,它不是一个失控的异常,被捕获并处理得很好。但是在这个操作之后,应用程序似乎执行了一个不需要的Exit()。

虽然编程文档会声明以下构造是不必要的,但我发现有时我必须使用以下构造

try
{
 using (DialogForm frm = new DialogForm())   
 {     
       DialogResult r = frm.ShowDialog();
       label1.Text = r.ToString();  
 }
}
catch (Exception ex)
{
    label1.Text = ex.Message;
}
catch
{
    label1.Text = "Unknown Exception";
}

虽然编程文档会声明以下构造是不必要的,但我发现有时我必须使用以下构造

try
{
 using (DialogForm frm = new DialogForm())   
 {     
       DialogResult r = frm.ShowDialog();
       label1.Text = r.ToString();  
 }
}
catch (Exception ex)
{
    label1.Text = ex.Message;
}
catch
{
    label1.Text = "Unknown Exception";
}

我记得dotnet有一个默认的异常处理程序,当异常跨越特定边界时会触发它。正是这个处理程序导致你的应用程序退出。我记得有一段时间以前看过这个问题,但不幸的是,我再也无法访问代码了。至于.NET和.NET CF之间行为上的差异,这是因为这两种处理帧的方式不同(可能CF中的帧没有父帧或类似的东西)


你可以挂接到这个默认的异常处理中,然后做你想做的任何事情。。。我认为我实现的代码是这样的:

我记得dotnet有一个默认的异常处理程序,当异常跨越特定边界时会触发该异常处理程序。正是这个处理程序导致你的应用程序退出。我记得有一段时间以前看过这个问题,但不幸的是,我再也无法访问代码了。至于.NET和.NET CF之间行为上的差异,这是因为这两种处理帧的方式不同(可能CF中的帧没有父帧或类似的东西)


你可以挂接到这个默认的异常处理中,然后做你想做的任何事情。。。我认为我实现的代码是这样的:

可能挂接
AppDomain.CurrentDomain.UnhandledException
(以及Joel的提示)解决了异常问题?可能类似于

我使用以下代码

    try
    {
        AppDomain.CurrentDomain.UnhandledException +=
            (object sender, UnhandledExceptionEventArgs e) =>
            {
                CrashOn((Exception)e.ExceptionObject, e.IsTerminating);
            };
        var mainWindow = new MainWindow();
        MobileDevice.Hibernate += (sender, e) => { mainWindow.Hibernate(); };
        Application.Run(mainWindow);
    }
    catch (Exception huh)
    {
        CrashOn(huh, false);
    }

在my的
Program.Main()
中。这里的
CrashOn()
方法将异常信息保存到磁盘,并启动崩溃恢复可执行文件。然后显示客户机崩溃的信息,可以通过邮件向我发送异常信息,并为用户提供退出或重新启动客户机的选项。

可能挂接
AppDomain.CurrentDomain.UnhandledException
(以及Joel的提示)解决了异常问题?可能类似于

我使用以下代码

    try
    {
        AppDomain.CurrentDomain.UnhandledException +=
            (object sender, UnhandledExceptionEventArgs e) =>
            {
                CrashOn((Exception)e.ExceptionObject, e.IsTerminating);
            };
        var mainWindow = new MainWindow();
        MobileDevice.Hibernate += (sender, e) => { mainWindow.Hibernate(); };
        Application.Run(mainWindow);
    }
    catch (Exception huh)
    {
        CrashOn(huh, false);
    }

在my的
Program.Main()
中。这里的
CrashOn()
方法将异常信息保存到磁盘,并启动崩溃恢复可执行文件。然后显示客户机崩溃的信息,可以选择将异常信息发送给我,并提供退出或重新启动客户机的选项。

在修补后,我发现了一些有效的方法:

try {
  // show Dialog that Throws
}
catch (Exception ex) {
  label1.Text = ex.Message;
  Application.DoEvents();  // this solves it
}

任何人只要能告诉我为什么需要DoEvents(),悬赏就可以了

修补之后,我发现了一些有效的方法:

try {
  // show Dialog that Throws
}
catch (Exception ex) {
  label1.Text = ex.Message;
  Application.DoEvents();  // this solves it
}

任何人只要能告诉我为什么需要DoEvents(),悬赏就可以了

关于这一点,我能找到的最好信息是您正在调用ShowDialog()

我试过使用Reflector,但它不能处理CF DLL。因此,最好的比较是查看主非CF文件。在它中,如果跟踪ShowDialog()函数,它将调用Application.RunDialog(form)。在那里,它创建一个新的线程上下文,并为对话框窗口运行自己的消息循环

由于我无法查看实际的CF DLL,我只能进行“有根据的猜测”。这似乎与异常发生在单独的消息循环上这一事实有关,除非您通过DoEvents()处理应用程序的消息队列,否则将无法正确捕获异常

因此,ShowDialog()基本上会导致在单独的消息循环中创建异常,除非调用DoEvents(),否则无法正确处理捕获到的异常


如果您尝试常规节目()会发生什么情况?你还需要我吗?我没有环境来测试这个,所以我只能建议你试试。如果您将其更改为Show()并且不再需要DoEvents(),我想我们就可以确定我是否正确。

关于这一点,我能找到的最好信息是您正在调用ShowDialog()

我试过使用Reflector,但它不能处理CF DLL。因此,最好的比较是查看主非CF文件。在它中,如果跟踪ShowDialog()函数,它将调用Application.RunDialog(form)。在那里,它创建一个新的线程上下文,并为对话框窗口运行自己的消息循环

由于我无法查看实际的CF DLL,我只能进行“有根据的猜测”。这似乎与异常发生在单独的消息循环上这一事实有关,除非您通过DoEvents()处理应用程序的消息队列,否则将无法正确捕获异常

因此,ShowDialog()基本上会导致在单独的消息循环中创建异常,除非调用DoEvents(),否则无法正确处理捕获到的异常

如果您尝试常规节目()会发生什么情况?你还需要我吗?我