2009-03-09 6 views
2

UIスレッド(進行状況バー)上のウィンドウコントロールによって発生した別のスレッドで長いプロセスを実行しているときにTargetInvocationExceptionが発生しました。この例外は、私のアプリをクラッシュさせ(デバッグのメインメソッドに行く)、try catchによって捕まえられませんでした。 私はこの例外を作り出し、それを修正しました(最大値を超える値で "値"プロパティを割り当てようとしていました)。しかし、私はこのような(生産コード内の)例外をキャッチすることができないので、アプリケーションを終了する代わりにアプリケーションを回復するオプションがあるのだろうと私に思い出させました。マルチスレッドでTargetInvocationExceptionからうまく回復するには?

答えて

2

あなたは非常に回復することはできません。あなたの操作の点では、エラーのために、多量のスタックフレーム(およびそれらのスタックフレームから参照されるオブジェクト)の状態はおそらく無効です。

このため、最高レベルで回復して操作を再試行できます。

アクセスしているリソースをトランザクションに含めることができれば、それを行うことをお勧めします。そうすることで、永続化されたデータの不一致について心配する必要はありません。

Best Practice for Exception Handling in a Windows Forms Application?

だけでなく、マイクロソフトからのアプリケーションブロックを例外処理:

また、あなたはSO上でこのスレッドをチェックアウトする場合があります

http://msdn.microsoft.com/en-us/library/cc309505.aspx

+0

@casperOne: "あなたの操作の点で、いくつかのスタックフレーム(およびそれらのスタックフレームから参照されるオブジェクト)の状態は、おそらくエラーのために無効です。"私の場合、例外は600回以上繰り返されています。 –

0

は、例外をキャッチし、それをメインコードまたは呼び出しコードに戻すメカニズムを見つけます。

2

静的イベントApplication.UnhandledExceptionを介して、GUIスレッド上で例外を処理することができます(実際には通知を受け取っているだけです)。

このイベントにハンドラをアタッチすると、WinForms UI(メッセージポンプ)スレッド上のすべての未処理の例外に対してハンドラが呼び出されます。このハンドラが添付されているという事実は、Applicationが終了しないことを意味します。これがなければ、WinFormsはアプリケーションをシャットダウンします。

0

あなたの3.0+がこれらの行に沿って何かできるのであれば、使用している.netのバージョンが不明です。

private void UpdateValue(int newValue) 
{ 
    Action myAction =() => progressBar.Value = newValue; 

    if (progressBar.InvokeRequired) 
     progressBar.Invoke(myAction); 
    else 
     myAction(); 
} 

このメソッドをプログレスバーの新しい値で呼び出すと、呼び出しにマーシャリングが必要かどうかがチェックされ、適切な呼び出しが行われます。 invokeRequiredは比較的高価ですので、必要な場所でのみ使用してください。これを拡張メソッドにして、必要に応じて他のコントロールにこのパターンを汎用的に使用することができます。

これが役に立ちます。

+0

@Dean:UIスレッドフォームから他のスレッドにアクセスすることによって例外が発生することはありませんが、この状況は適切に反映されています。それは、どこに例外がスローされ、捕まえられなかったのかをあなたの中で(myAction)呼び出すとしましょう。試してみてください...ありがとう –

関連する問題