In my application (.NET 4.0) I use smartassembly for error reporting with a custom template. It installs two handlers:
- It installs a global exception catcher, and calls my custom code if an exception occurs. There I display a WPF window which shows the details of the exception and allows the user to send the data via the internet.
- If an exception occurs which cannot be handled by #1, it calls a fatal exception handler. There I output the exception data in a message box.
On one customer's machine (Windows XP, .NET 4.0) he gets an error message from #2 after the application starts. Then the application is terminated:
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)
The relevant code:
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
}
}
So the following happens:
- During startup an exception occurs (unfortunately, this gets lost).
- To handle the exception, smartassembly calls the handler #1, OnReportException().
- There I create a new ErrorReportView.
- WPF throws a cross-thread exception in the constructor (before
InitializeComponent())! - Because an exception occurred while handling the exception, smartassembly calls the handler #2 and terminates the application.
How is it possible that a simple new Window() can cause a cross-thread exception on itself?