0

私の理解では、Windows フォーム アプリケーションでは、UI スレッドが例外をスローし、それがユーザー コードによって処理されない場合、アプリケーションはユーザーに明らかな方法でクラッシュします。(アプリケーションがクラッシュしたか、ウィンドウがフリーズするか、またはその両方であることを示すメッセージが画面に表示されます)

ここで、次のコードを検討してください。

try
{
     PerformAsyncOperation();
     while(!async_op_complete)
     {
           Application.DoEvents();
     }
}
catch
{
    Print("exception");
}

私の理解では、Windows フォームには同期コンテキストがあるため、非同期操作 (ちなみに、.net 4.5 については話していません) は、制御がイベント ハンドラー プロシージャを離れるまで実行されません。それが発生すると、UI スレッド内で非同期コードが実行されます。そのコードが例外をスローした場合、非同期メソッドの呼び出しを囲む try-catch ステートメントによってキャッチされません。これは、例外がスローされるまでに制御がその try-catch ステートメントをすでに離れているためです。

ただし、上記のような場合、ループしているという事実は、制御が UI スレッド内に残っていることを意味し、ループ内で Application.DoEvents() を呼び出しているという事実は、非同期操作が内部で「非同期的に」実行されることを意味します。 UI スレッド。また、そのループは try 句内で発生するため、async メソッドによってスローされた例外は、対応する catch 句によってキャッチされます。(少なくともこれは私が観察した動作です。)

そうは言っても、

  1. 同じ UI スレッド内でさらに作業を行う前に、非同期操作が完了するのを待っている間に UI の応答性を維持するために、ループ内で Application.DoEvents() を呼び出すことは良い考えですか?

  2. ループ内で Application.DoEvents() を呼び出すのは良い考えではありませんが、PerformAsyncOperation() によってスローされた例外を catch 句が処理した後、アプリケーションが静かに終了する (ウィンドウがフリーズせず、エラー メッセージも表示されない) のはなぜでしょうか?

4

1 に答える 1

1

1) ループ内で Application.DoEvents() を呼び出して、非同期操作が完了するのを待っている間に UI の応答性を維持してから、同じ UI スレッド内でさらに作業を行うことをお勧めしますか?

絶対違う!DoEvents()悪であり、あらゆる種類の問題を引き起こします。

2) ループ内で Application.DoEvents() を呼び出すのは良い考えではありませんが、PerformAsyncOperation() によってスローされた例外を catch 句が処理した後、アプリケーションが静かに終了する (ウィンドウがフリーズせず、エラー メッセージも表示されない) のはなぜですか?

何をするかわからずに言うのは難しいPerformAsyncOperation()。明示的に new Thread( またはTask) を使用しない限り、ループの前に同期的に実行されます。

アプリの終了については、説明できません。

worker でキャッチされていない例外がスローされた場合Thread、アプリは「動作を停止しました」ダイアログ ボックスを表示して終了します。

変更されたことがわかっている唯一のことは、キャッチされていない例外が内部からスローされたときの動作Taskです。.NET 4.5 より前では、Thread.

.NET 4.5 をインストールしている場合 (アプリが 4.0 をターゲットにしている場合でも)、 a でキャッチされていない例外がTask静かに飲み込まれるようになりました。

動作を説明する記事は次のとおりです。 MSDN: Task Exception Handling in .NET 4.5

于 2013-03-21T15:49:27.540 に答える