これが私の仮定の例です。ボタンが1つ付いた非常に単純なWPFウィンドウがあります。 Button.Clickイベントには、このようなハンドラがあります。
Action doit = () =>
{
Action error = () => { throw new InvalidOperationException("test"); };
try {
this.Dispatcher.Invoke(error, DispatcherPriority.Normal);
} catch (Exception ex) {
System.Diagnostics.Trace.WriteLine(ex);
throw;
}
};
doit.BeginInvoke(null, null);
私は例外がキャッチされて、それによって書き留められることを期待するでしょうTrace.WriteLine
コール。代わりに、例外はキャッチされず、アプリケーションは中断します。
誰かがこれが起こる可能性のある説明を知っていますか?とによって呼び出されたデリゲートによってスローされた例外をキャッチするためにどのような回避策を提案しますかDispatcher.Invoke
?
更新1:入れますthrow
例外処理コードで。私は実際に例外を無視したくありません。私の質問の全てのポイントはそれを正しく扱うことです。問題は、例外処理コードが実行されないことです。
これは架空の例です。私の本当のコードはそのようには見えません。また、呼び出されるメソッド内のコードを変更できないとします。
更新2:この同様の例を考えてください。 WPFウィンドウの代わりに、Windowsフォームウィンドウがあります。それはほぼ正確に同じハンドラを持つボタンを持っています。唯一の違いは呼び出しコードにあります。こんなふうになります。
this.Invoke(error);
Windowsフォームでは、例外処理コードが実行されます。なぜ違いがありますか?
更新しました:他のスレッドの例外を観察するには、Task
、それをキューに入れるDispatcher
スレッド(TaskScheduler.FromCurrentSynchronizationContext
そして、それを待ってください。
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Action doit = () =>
{
var error = Task.Factory.StartNew(
() => { throw new InvalidOperationException("test"); },
CancellationToken.None,
TaskCreationOptions.None,
ui);
try {
error.Wait();
} catch (Exception ex) {
System.Diagnostics.Trace.WriteLine(ex);
}
};
doit.BeginInvoke(null, null);
更新された(再び):あなたの目標は再利用可能なコンポーネントなので、私はTask
ベースのインターフェースまたは他のものに基づくものSynchronizationContext
のようなイベントベースの非同期パターンコンポーネントをベースにする代わりに、Dispatcher
またはISynchronizeInvoke
。
Dispatcher
ベースのコンポーネントはWPF / Silverlightでのみ機能します。ISynchronizeInvoke
ベースのコンポーネントはWindowsフォームでのみ機能します。SynchronizationContext
ベースのコンポーネントは、WPFやWindowsフォーム、そして(もう少し手を加えて)ASP.NET、コンソールアプリケーション、ウィンドウサービスなどと透過的に動作します。
イベントベースの非同期パターンは、古いお勧めの書き方です。SynchronizationContext
ベースのコンポーネント.NET 3.5時代のコードではまだ出回っています。 .NET 4を使用している場合は、タスク並列ライブラリのほうがはるかに柔軟でクリーン、そして強力です。のTaskScheduler.FromCurrentSynchronizationContext
用途SynchronizationContext
このような同期を必要とする再利用可能なコンポーネントを書くための新しい方法です。
Dispatcher
糸。 - Stephen ClearyTask
例外を伝播します。 - Stephen ClearyTask
ベースのインターフェースまたは他のものに基づくものSynchronizationContext
のようなイベントベースの非同期パターン。その理由はSynchronizationContext
ベースのアプローチは、WPFやWindowsフォーム、そして(もう少し手を加えて)ASP.NET、コンソールアプリケーション、ウィンドウサービスなどを透過的に機能させるでしょう。SynchronizationContext
。 - Stephen Cleary