1

C# winforms アプリケーションのメイン スレッドに影響を与えずに多数の UI 更新を実行する方法はありますか?

ユーザーが特定のイベントをクリックしたときの長い遅延を避けたいです (私の場合、メモリを破棄するための多くのクローズ フォーム コールです)。

「do work」イベントで長い操作を実行するために使用できることはわかっBackgroundWorkerていますが、問題は、このイベントでUIを変更できないことです(クロススレッド例外が発生します)-したがって、多数のクローズフォームを配置できませんここに呼び出します。

また、これはメインスレッドで実行され、最終的にメインスレッドをロックアップしてユーザーエクスペリエンスを低下させるため、クローズフォーム呼び出しを「worker completed」イベントに入れることはできません。

アプリケーション セッションがアイドル状態の場合にのみクローズを処理するスレッドを生成することを考えましたが、これが少し厄介になるかどうかはわかりません。

4

1 に答える 1

2

UI を更新するには、 BackgroundWorkerのProgressChangedイベントを使用する必要があります。この機能を有効にするには、 BackgroundWorkerインスタンスのWorkerReportsProgressプロパティを に設定します。その後、 DoWorkイベント ハンドラーからデータを送信することで、UI を何度も更新できます。true

backgroundWorker.ReportProgress(percentage, yourCustomData);

Windows フォーム コントロールへのスレッド セーフな呼び出しを行うことをお勧めします。理由は次のとおりです。

Windows フォーム コントロールへのアクセスは、本質的にスレッド セーフではありません。コントロールの状態を操作するスレッドが 2 つ以上ある場合、コントロールを強制的に矛盾した状態にすることができます。競合状態やデッドロックなど、その他のスレッド関連のバグも考えられます。コントロールへのアクセスがスレッドセーフな方法で行われるようにすることが重要です。

.NET Framework は、スレッド セーフではない方法でコントロールにアクセスしていることを検出するのに役立ちます。デバッガーでアプリケーションを実行しているときに、コントロールを作成したスレッド以外のスレッドがそのコントロールを呼び出そうとすると、デバッガーは InvalidOperationException を発生させ、次のメッセージを表示します。に作成されました。」

この例外は、デバッグ中、および場合によっては実行時に確実に発生します。この問題が発生した場合は、修正することを強くお勧めします。

その例外を無効にすることができます:

Form.CheckForIllegalCrossThreadCalls = false;

しかし、コントロールが機能しなくなる可能性があります (いつかそうなるでしょう)。

于 2012-10-31T12:24:44.683 に答える