【问题标题】:Unable to show a window from AppDomain.CurrentDomain.UnhandledException that catches an exception in a foreground thread - WPF无法从 AppDomain.CurrentDomain.UnhandledException 显示在前台线程中捕获异常的窗口 - WPF
【发布时间】:2018-03-09 04:36:14
【问题描述】:

我正在阅读 C# 简而言之(线程章节),并试图捕获一个除以零的异常,该异常是我从按钮事件处理程序中抛出的一个新线程。 AppDomain.CurrentDomain.UnhandledException 按预期触发。事件处理方法只是显示一个名为“ErrorWindow”的窗口。当我进入窗口的构造函数时,调试器抛出异常并且窗口不显示。

这是我所拥有的:

  1. 目标框架:4.5.2
  2. 目标平台:X64

该应用程序是一个 WPF windows 应用程序,包含两个窗口:

  1. MainWindow:有一个按钮,可以执行下面的代码 sn-p。
  2. ErrorWindow:在 AppDomain.CurrentDomain.UnhandledException 事件处理程序中显示的只是一个空白窗口

代码sn-p:

var thread = new Thread(() =>
{
int result = 100 / int.Parse("0");
});
thread.Start();

我在 App.xaml.cs 的 StartUp 事件处理程序中附加了 AppDomain.CurrentDomain.UnhandledException 事件处理程序。事件处理程序只需创建一个 ErrorWindow 实例并尝试显示它。

如果有人能够重现这种行为并解释原因,那就太好了。如果需要,我会分享我的 VS 项目。

PS:这只会在我创建线程时发生。如果我的 DivideByZeroException 是从主 UI 线程抛出的,那么窗口会按预期显示。

PS:将窗口的显示编组到 UI 线程不起作用,我不希望它这样做。 谢谢!

【问题讨论】:

  • 您对使用Thread有什么特殊要求吗? Task 通过为您提供一种受支持的方式来捕获和观察异常,从而使这种情况变得更加容易
  • 我没有要求。我更喜欢使用线程,因为我可以。谢谢@KevinGosse!

标签: c# wpf multithreading exception appdomain


【解决方案1】:

恕我直言,AppDomain.UnhandledException Event 并不意味着显示窗口或错误对话框。如备注部分所述:

此事件提供未捕获异常的通知。它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。如果有关应用程序状态的足够信息可用,则可以采取其他措施——例如保存程序数据以供以后恢复。建议小心,因为如果不处理异常,程序数据可能会损坏。

相反,如果你想捕获异常并处理它,你可以使用Application.DispatcherUnhandledException Event。在这种情况下,您可以通过将Handled 属性设置为true 来使您的应用程序保持活动状态:

Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;

private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    e.Handled = true;
    /* Show your error window */
}

但要注意,因为:

如果在后台用户界面 (UI) 线程(具有自己的 Dispatcher 的线程)或后台工作线程(没有 Dispatcher 的线程)上未处理异常,则不会将异常转发到主 UI 线程.因此,不会引发 DispatcherUnhandledException。

希望对你有帮助。

【讨论】:

  • 您提到的两个事件处理程序都不处理非ui线程。我的问题 is 与非 ui 线程有关。我同意它不应该显示一个窗口,但我想知道这是否可能以及如何。还有另一种方法可以使用 app.config 中启用的旧版未处理异常策略来阻止应用程序终止。
  • @JLILIAmen 我强烈建议不要在您的 app.config 中启用旧的未处理异常策略。没有你需要的处理程序(对于非 ui 线程),所以也许你需要改变你的方法。为什么不在非 ui 线程中捕获异常?
  • @JLILIAmen 您评论了“您提到的两个事件处理程序都不处理非 ui 线程”。这并不完全正确。第一个处理程序确实在 appDomain 的每个线程中处理异常。我谈到了您必须在全球范围内“捕获”异常的选项。这并不能解决您的问题,但它是一种表示您的问题可能没有解决方案,而是改变方法的方式。
猜你喜欢
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
  • 2018-07-01
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
相关资源
最近更新 更多