BackgroundWorkerの未処理例外について
質問
私は、BackgroundWorkerオブジェクトを利用して長時間実行する小さなWinFormsアプリを持っています。
バックグラウンド操作では、誰かがファイルを開いていて、それが再作成されるときなど、時折例外が発生します。
コードが IDE から実行されるかどうかに関係なく、.NET はユーザーに未処理の例外が発生したことを通知するエラー ダイアログをポップアップ表示します。 Release 構成を使用してコードをコンパイルしても、これは変わりません。
によると MSDN :
<ブロッククオートコードが処理しない例外を発生させた場合、BackgroundWorker は例外をキャッチして RunWorkerCompleted イベント ハンドラーに渡し、そこで System.ComponentModel...:.RunWorkerCompletedEventArgs の Error プロパティとして公開されます。Visual Studio デバッガーの下で実行している場合、デバッガーは DoWork イベント ハンドラーで未処理の例外が発生した箇所でブレークします。
これらの例外が時々スローされることを期待し、DoWork 内ではなく RunWorkerCompleted イベントで処理したいと思います。 私のコードは適切に動作し、エラーは RunWorkerCompleted イベント内で正しく処理されますが、"Unhandled exception" について文句を言う .NET エラー ダイアログの発生を停止する方法がどうしてもわかりません。
BackgroundWorker はそのエラーを自動的にキャッチするはずではありませんか? MSDN のドキュメントにはそのように記載されていないのでしょうか? .NET に、このエラー は が処理されていることを.NETに知らせると同時に、例外がRunWorkerCompletedEventArgsのErrorプロパティに伝播することを可能にする必要がありますか?
どのように解決するのですか?
あなたが記述していることは、BackgroundWorkerの定義された動作ではありません。何か間違ったことをしているのではないでしょうか。
以下はBackgroundWorkerが例外を食べることを証明する小さなサンプルです。 DoWork で例外を受け取り、それを RunWorkerCompleted :
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
throw new InvalidOperationException("oh shiznit!");
};
worker.RunWorkerCompleted += (sender, e) =>
{
if(e.Error != null)
{
MessageBox.Show("There was an error! " + e.Error.ToString());
}
};
worker.RunWorkerAsync();
私のサイキックデバッグスキルが、あなたの問題を明らかにしてくれています。RunWorkerCompleted ハンドラで e.Result にアクセスしています。もし e.Error があれば、e.Result にアクセスせずに処理する必要があります。たとえば、次のコードは悪い、悪い、悪い、実行時に例外をスローします。
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
throw new InvalidOperationException("oh shiznit!");
};
worker.RunWorkerCompleted += (sender, e) =>
{
// OH NOOOOOOOES! Runtime exception, you can't access e.Result if there's an
// error. You can check for errors using e.Error.
var result = e.Result;
};
worker.RunWorkerAsync();
RunWorkerCompletedイベントハンドラの適切な実装を紹介します。
private void RunWorkerCompletedHandler(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
DoSomethingWith(e.Result); // Access e.Result only if no error occurred.
}
}
VOILA, ランタイムエクストラクションを受けなくなります。
関連
-
[解決済み】コレクションが変更され、列挙操作が実行されないことがある。
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み] 複数の例外を1行でキャッチする(ブロックを除く)
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] 最近のPythonでカスタム例外を宣言する適切な方法?
-
[解決済み] Javaにおけるチェック済み例外とチェックされていない例外の理解
-
[解決済み】C#で例外をキャッチして再スローする理由とは?
-
[解決済み] ASP.NET Web Apiで処理されない例外をすべてキャッチする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み】 C# 条件演算子エラー 代入、call、increment、decrement、await、new object 式のみ文として使用可能です。
-
[解決済み】「namespace」なのに「type」のように使われる。
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である