私のアプリケーション (.NET 4.0) では、カスタム テンプレートによるエラー レポートに smartassembly を使用しています。2 つのハンドラーをインストールします。
- グローバル例外キャッチャーをインストールし、例外が発生した場合はカスタム コードを呼び出します。そこで、例外の詳細を表示し、ユーザーがインターネット経由でデータを送信できるようにする 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 を呼び出し、アプリケーションを終了します。
単純な new Window() がそれ自体でクロススレッド例外を引き起こす可能性があるのはどうしてですか?