3

重複の可能性:
.NETがクロススレッド操作を許可しないのはなぜですか?
UIスレッドのみがUIの変更を許可されているのはなぜですか?

私が理解したことから、.netが不正なクロススレッド呼び出しの例外を発生させる理由は、GUIが不確定な動作を示す可能性があるためです。

しかし、これは他のすべてのオブジェクトには当てはまりませんか?コードによっては、2つのスレッドが同じオブジェクトで機能する場合、オブジェクトは不確定な状況にある可能性があります。では、なぜこの例外が制御要素に存在するのでしょうか。または、この例外が制御要素専用であるのはなぜですか。

そして、invokeの使用はどのように役立ちますか?それはまだ不確定です。

4

3 に答える 3

4

Invokeコントロールへのクロススレッド呼び出しは許可されていないため、他のスレッドでのコントロールが必要です。この制限が存在する理由に関するより完全な議論については、そのリンクを読む必要があります-ここでは答えませ

呼び出しInvokeは、バックグラウンド スレッドが UI スレッドで "何かを行う" ことを可能にするため、私たちを助けてくれます。メソッドを直接呼び出すのではなく、"機会があれば実行してください"というWindows メッセージを送信するため機能します。UI スレッドは、そのスレッドに送信されたすべてのメッセージを継続的に処理するメッセージ ポンプを実行しています。多くの場合、これらのメッセージは"ユーザーがこのボタンをクリックしました" のようなものです。この場合、Windows フォームはClick、関連するコントロールでイベントを発生させることによってこのメッセージを処理します。この場合、Windows フォームは、指定されたデリゲートを実行してメッセージを処理します。

その結果、任意の時点で 1 つのスレッド (UI スレッド) だけが UI コントロールを変更または操作することになります。

Invokeデリゲートが実行される順序については保証されないことに注意してください。Invoked2 つの異なるスレッド (または同じスレッド) からの 2つのデリゲートが正しい順序で実行されることが重要である場合、それは別の問題です。


余談:ほとんどのアプリケーションにはすべてのコントロールが作成される 1 つのスレッドがあるため、"UI スレッド" について説明しますが、実際にはさまざまなコントロールをスレッドで作成できます。つまり、メッセージを処理するコントロールが作成されたスレッドです。これらのメッセージが適切に処理されるためには、明らかに、そのスレッドでメッセージ ポンプが実行されている必要があります。

于 2012-10-16T13:01:06.007 に答える
2

ほとんどの型は実際にはスレッド セーフではありませんが、一度に1 つのスレッドのみが使用する限り、複数のスレッドから使​​用できます。

UI コントロールはまったく同じではありません。スレッド アフィニティがあります。UI スレッドでのみ安全に使用できます。

この理由の 1 つは、UI スレッドがいつでもそれらを再描画する可能性があるため、いつでも使用できるようにする必要があるためです。それを、ロックを待機している間 UI スレッドを遅らせたくないことと組み合わせ、また、できる限り競合しないロックを回避したいという欲求と組み合わせます (UI スレッドがロックを取得する場合は、多くのロックを取得する必要があります)。すべてのアクセスに対してこれを行う必要があります)、単純化されたモデルが得られ、すべてのアクセスが UI スレッド上にある必要があると言うだけで簡単になります。スレッド アフィニティなしで UI フレームワークを設計することは可能だと確信していますが、それを実行して予測どおりに動作させるのは難しいでしょう。

于 2012-10-16T12:53:44.197 に答える
0

Invokeは、正しいスレッドでUIを呼び出していることを確認するために使用されます。ただし、これはすべての.netオブジェクトに必要です。UIは単一のスレッドで機能するように作成されています(これはWPFとWinformsに当てはまります)。2つの異なるスレッドは、同時にではない限り、同じオブジェクトにアクセスできます。これが発生すると、レースケースが作成され、デッドロックが発生する可能性があります

于 2012-10-16T12:49:11.903 に答える