40

ここで説明されているように、GUI コントロールへのクロススレッド アクセスの一般的なセットアップを見てきました

私が見つけたすべての Web ヒットは、同様のことを説明しています。

しかし、なぜ InvokeRequired を確認する必要があるのでしょうか。Invoke を直接呼び出すことはできませんか?

答えはノーだと思いますので、私の本当の質問は「なぜ」ですか?

4

6 に答える 6

32

非 UI スレッドから UI に触れることはできません。コントロールにはスレッド アフィニティがあるため、非常に悪いことが起こる可能性があります。そのため、非 UI スレッドから (少なくとも) Invokeorを呼び出す必要がありBeginInvokeます。

ただし、UI スレッドの場合は、多くの時間を呼び出したくありません。Invoke問題は、既に UI スレッドを使用している場合でも、フォームのポンプにメッセージを送信して処理するという不必要なオーバーヘッドがまだあることです。

実際には、ほとんどのスレッド化コードでは、UI スレッドで特定のメソッドが呼び出されることが予想されるため、そのような場合、追加のオーバーヘッドはありません。Invoke

于 2009-04-14T12:00:36.467 に答える
3

InvokeRequired基本的に、正しいスレッドで実行しているかどうかがわかります。正しいスレッドにいない場合は、タスクを正しいスレッドにマーシャリングする必要があります。そうでない場合はそうしません。したがって、チェックが必要です。

于 2009-04-14T12:00:09.633 に答える
3

ウィンドウ ハンドルが作成される前に呼び出そうとすると (たとえば、フォーム コンストラクターを呼び出すとき) InvalidOperationException、. そのため、一般的にInvokeRequiredチェックが必要です。

詳細については、 MSDNを参照してください。

于 2012-04-18T12:22:55.173 に答える
1

問題は、GUI コントロールには、GUI コントロールのインスタンス化に使用されたのと同じスレッドで実行されるコードのみが GUI コントロールにアクセスできるという要件があることです。この要件の背後にある理由は、Windows の設計方法に関係しています。これを変えるのは非常に難しいと言っておきましょう。

InvokeRequired は、インスタンス化スレッドの ID に対して、現在実行中のスレッドの ID をチェックします。それらが同じである場合、コードはコントロールと自由に対話できます。そうでない場合、コードは現在のスレッドからインスタンス化スレッドまでデータをマーシャリングする必要があります。これは時間とコストのかかるプロセスであり、可能な限り回避する必要があります。常に呼び出すとコードは機能し、パフォーマンスの低下に気付かない可能性がありますが、マルチコア システムが使用されるようになると、このシナリオはますます一般的になります。後で元に戻す必要があるコードの「結び目」を作成しないことをお勧めします。

于 2009-04-14T12:37:05.490 に答える
0

Invoke は、コストがかかる直接ではなく、Delegate を介してコードを呼び出します。

必要な場合にのみ Invoke を呼び出すと、費用対効果が高くなります。したがって、InvokeRequired は、呼び出しが同じスレッドから行われたのか、それとも別のスレッドから行われたのかを調べるために使用されます。

于 2009-04-14T12:01:02.643 に答える
0

私が考えることができる 1 つの理由は、パフォーマンスです。ほとんどの場合、呼び出し元のスレッドが作成元のスレッドと同じである場合、不必要なオーバーヘッドが発生します。

于 2009-04-14T12:04:07.347 に答える