2009-02-26 1 views
0

私は.NETでControl.Invoke(デリゲート)を使用してコントロールの操作を行う必要があることを理解しています。これは私に、Invokeが実際に必要な環境があるのか​​疑問に思った。私が知る限り、Visual BasicやPascalの古いバージョンでは必要ではありませんでした。具体的には、Java(バージョン依存の可能性はあるでしょうか?)と "古いスタイル"のWindows GUIプログラミング(手動でメッセージキューを読む)の状態はどうですか?GUI操作のために呼び出される言語/プラットフォームは何ですか?

答えて

1

ほとんどの言語では、GUI操作のための呼び出しが必要です。 JavaではSwingUtilities.invokeLaterがあります。実際には、複数のスレッドが使用されている場合は、どのような環境でもそのようなメソッドが必要になります。その理由は、メインUIスレッドがイベント通知メカニズムを実行するためです。このメカニズムと対話できる2番目のスレッドは、何らかの形でそれと同期する必要があります。

これらの呼び出しメソッドは、実際には開発者にとって便利です。存在しないプラットフォームでは、別のスレッドからUI項目にアクセスすることが許可されているわけではありません。これは、開発者がカスタムメカニズム(イベント送信)を実装して、そのようにする必要があることを意味します。 UIコードはスレッドセーフではありません。私は多くのプラットフォームとテクノロジーを扱ってきました。私は常にこのルールに従っています.1つのスレッドだけからUIに触れてください。

0

実際、NO。 GUIが1つ以上のスレッドを実行している場合にのみ必要です。 WinForm(およびWPF)アプリケーションでは、GUIは単一スレッドのSTAスレッド上で実行されています(これはCOMにまでさかのぼりますが、私は正直に分かっていないので、なぜそうなのか尋ねません)。

STAスレッドで作成されたオブジェクトを別のスレッドから呼び出すと、例外がスローされることを確認するためのチェックが行われます。これはWPFと同じですが、WPFはこれをよりエレガントにします。

とにかく、Invokeが必要な場合は、そのプロパティがあるため実際に確認できます。このパターンは、WinFormアプリケーションで複数のスレッドを処理するのに役立つことが示唆されています。

​​

上記のコードは、Textプロパティを設定するための方法を提供しています。必要に応じて調整することができます。

+0

これはSTAthreadとは関係ありません。 STAthreadはCOMに関連していますが、相互運用性の目的でのみ使用されます。 Windowsでは、STAまたはMTAを作成したスレッドと同じスレッドでコントロールの更新が発生する必要があります。 –

1

あなたは間違っています。 Control.Invokeは、コントロールに対して操作を実行する必要はありません。

Control.Invokeは、スレッド境界を越えてコードをマーシャリングするのに役立つ便利なツールですが、それを行う唯一の方法ではありません。これは、バックグラウンドスレッドで何らかの作業を行うときに最も頻繁に使用されます。

Windowedコントロール(つまり、Windowsのウィンドウハンドルを持ち、メッセージポンプ経由でメッセージを処理するコントロール)を更新する必要があるバックグラウンドスレッドからコードを呼び出すときは、そのプロパティを変更するか、 MessagePumpスレッドに制御を渡す必要があります.Control.Invokeはその実装に便利な方法です。

すべて Windowsで実行されるプログラムでは、バックグラウンドスレッドのコントロールを更新する関数を呼び出すことはできません。いくつかの言語がバックグラウンドでこの詳細を扱うかもしれませんが、私はそのことについて何も知らないのです。

1

Invokeは、Win32 API PostMessageのラッパーです。ウィンドウを所有するスレッドのみがウィンドウにアクセスできます。これは、Windowsがシングルスレッド化された時代にまで伝わってきた伝統です。つまり、PostMessageは、あなたが使っているもの(VB6、Delphi、.NETなど)に関係なく、Windows上の真のウィンドウにアクセスする正しい方法ですが、さまざまなプログラミング言語は人生を楽にするラッパーを提供します。

関連する問題