在我的应用程序(.NET 4.0)中,我使用smartassembly进行错误报告并使用自定义模板。它安装了两个处理程序:创建WPF窗口时发生跨线程异常
- 它安装全局异常捕获器,并在发生异常时调用我的自定义代码。在那里,我显示一个WPF窗口,显示异常的细节,并允许用户通过互联网发送数据。
- 如果发生无法由#1处理的异常,它会调用致命的异常处理程序。在那里,我在消息框中输出异常数据。
在一台客户机器(Windows XP,.NET 4.0)上,他在应用程序启动后从#2中收到错误消息。然后应用程序被终止:
System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.Threading.Dispatcher.VerifyAccess()
at Exapt.ErrorReporting.ErrorReportView..ctor()
at Exapt.ErrorReporting.ExaptUnhandledExceptionHandler.OnReportException(ReportExceptionEventArgs e)
at SmartAssembly.SmartExceptionsCore.UnhandledExceptionHandler.ReportException(Exception exception, Boolean canContinue, Boolean manuallyReported)
相关的代码:
public ExaptUnhandledExceptionHandler : UnhandledExceptionHandler
{
protected override void OnReportException(ReportExceptionEventArgs e)
{
var view = new ErrorReportView();
view.DataContext = new ErrorReportViewModel(this, e, view);
view.ShowDialog();
}
}
public ErrorReportView : Window
{
public ErrorReportView()
{
this.InitializeComponent();
// EDIT
if (Application.Current != null)
this.Owner = Application.Current.MainWindow;
// END EDIT
}
}
所以会发生以下情况:
- 在启动过程中发生异常情况时(不幸的是,这种丢失)。
- 为了处理异常,smartassembly调用处理程序#1,OnReportException()。
- 那里我创建了一个新的ErrorReportView。
- WPF在构造函数中抛出一个跨线程异常(在
InitializeComponent()
之前)! - 由于处理异常时发生异常,smartassembly调用处理程序#2并终止应用程序。
一个简单的新Window()如何可能导致自身的跨线程异常?
我不知道smartAssembly知识,但它似乎OnReportException方法是在一个线程是不是UI胎面执行。您是否尝试通过Application.Current.Dispatcher.Invoke方法创建ErrorReportView?编辑:这是一个值得尝试的答案。 – Sisyphe
不要太在AppDomain.UnhandledException的事件处理程序中花哨。它在遭受崩溃的线程上产生,因此创建一个WPF窗口不会起作用。保持简单,记录错误,并挤出一个MessageBox,不再。 –
@HansPassant我必须有些奇特,因为数据通过互联网发送,我需要用户的同意。 –