方法 : スレッドからコントロールを操作する
BackgroundWorker コンポーネントは、BeginInvoke メソッドに代わると共に追加の機能を提供します。ただし、BeginInvoke メソッドは、下位互換性を保つ目的および将来使用する目的で保持されます。 詳細については、「BackgroundWorker コンポーネントの概要」を参照してください。
マルチスレッドは、プロセッサ集中型のクラス モジュール プロシージャを実行するときに最適です。 他のコンポーネントとは異なり、別のスレッドに属するコントロールのメソッドを直接呼び出すことにはいくつかの問題があります。 コントロールに作用するメソッドは、そのコントロールが作成されたスレッドで実行される必要があります。 あるスレッドからの呼び出しをマーシャリングして、スレッドの境界を越えて他のスレッドに送ると、非常に多くのシステム リソースが浪費されます。したがって、他のスレッドのコントロールを繰り返し呼び出すことは避ける必要があります。 別のスレッドから直接呼び出すことはリソースの浪費につながり、アプリケーションのパフォーマンスに影響を与えます。 最悪のケースでは、アプリケーションのデッドロックを引き起こし実行がフリーズする可能性もあります。
ただし、スレッドからコントロールのメソッドを呼び出すことが必要な場合もあります。 たとえば、スレッドによって実行されたアクションに応答して、フォームのボタンを無効にしたり、表示を更新したりするメソッドを呼び出す場合などがあります。 .NET Framework には、他のスレッドによって所有されるコントロールと対話するメソッドを呼び出すために、どのスレッドからでも安全に呼び出すことのできるメソッドが用意されています。 BeginInvoke メソッドにより非同期実行が開始されるのに対し、Invoke メソッドを使用するとコントロールでメソッドの同期実行が可能になります。 これらのメソッドを使用するには、呼び出すメソッドと同じシグネチャを持つデリゲートを宣言する必要があります。 呼び出すメソッドに対して適切なデリゲートを指定することにより、フォームの任意のコントロールの Invoke メソッドまたは BeginInvoke メソッドを呼び出すことができます。 必要なパラメーターは Object にラップされ、対象のメソッドに転送されます。
別のスレッドによって所有されるコントロールを含むメソッドを呼び出すには
呼び出すメソッドと同一のシグネチャを持つデリゲートを宣言します。
整数型 (Integer) および文字列型 (String) の各パラメーターを持つデリゲートを宣言する例を次に示します。
Public Delegate Sub myDelegate(ByVal anInteger as Integer, ByVal _ aString as String)
public delegate void myDelegate(int anInteger, string aString);
任意のコントロールを使用して、他のスレッドによって所有されるコントロールを操作するメソッドを呼び出します。
注意
メソッドによって要求されるパラメーター (指定されている場合) は Object 内で指定できます。
メソッドの同期呼び出しを行うには、Control.Invoke メソッドを呼び出します。
Label1.Invoke(New myDelegate(AddressOf myMethod), New _ Object() {1, "This is the string"})
Label1.Invoke(new myDelegate(myMethod), new Object[] {1, "This is the string"});
メソッドの非同期呼び出しを行うには、Control.BeginInvoke メソッドを呼び出します。
Label1.BeginInvoke(New myDelegate(AddressOf myMethod), _ New Object() {1, "This is the string"})
Label1.BeginInvoke(new myDelegate(myMethod), new Object[] {1, "This is the string"});
参照
処理手順
チュートリアル : Visual Basic による簡単なマルチスレッド コンポーネントの作成
チュートリアル : Visual C# による簡単なマルチスレッド コンポーネントの作成