CでのInvokeとBeginInvokeの違い#



Difference Between Invoke



元のリンク

関連情報: InvokeとBeginInvokeの本当の意味マルチスレッドでWinformを呼び出す方法



Control.Invokeメソッド(デリゲート):このコントロールのベースウィンドウハンドルを所有するスレッドで、指定されたデリゲートを実行します。

Control.BeginInvokeメソッド(デリゲート):コントロールの基本ハンドルが作成されたスレッドで、指定されたデリゲートを非同期的に実行します。



ControlのInvokeとBeginInvokeは、スパースレッドに関連しています(通常、メインスレッドuiを更新するためにスパースレッドで呼び出されるため)Invokeは実行のためにメインスレッドにすぐに挿入され、BeginInvokeはメインスレッドが終了するまで実行されません。

(1)InvokeとBeginInvokeを制御します
以下に基づいて理解する必要があります。
(1)InvokeおよびBeginInvoke of Controlは、InvokeおよびBeginInvoke ofDelegateとは異なります。
(2)コントロールのInvokeパラメーターとBeginInvokeパラメーターはデリゲートであり、デリゲートされたメソッドは、通常UIスレッドと呼ばれるコントロールスレッドで実行されます。

[コードI]制御の呼び出し



/ * Control Invoke * / private delegate void InvokeDelegate() private void InvokeMethod() { // C code segment } private void butInvoke_Click(object sender, EventArgs e) { // A code snippet ... this.Invoke(new InvokeDelegate(InvokeMethod)) // B code segment ... }

コードの実行順序は何だと思いますか? Control InvokeとBeginInvokeは、メインスレッドであるUIスレッドで実行されることに注意してください。
A ----------------> C ----------------> B
説明:

(1)UIスレッドでAが実行された後、Invokeを開始し、Invokeは同期します
(2)コードセグメントBは実行されませんが、InvokeMethodメソッドであるコードセグメントCは、UIスレッドですぐに実行されます。
(3)InvokeMethodメソッドが実行された後、コードセグメントBはUIスレッドで実行を継続します。

[コードII] BeginInvoke of Control

/ * Control's BeginInvoke * / private delegate void BeginInvokeDelegate() private void BeginInvokeMethod() { // C code segment } private void butBeginInvoke_Click(object sender, EventArgs e) { // A code snippet ... this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod)) // B code segment ... }

コードの実行順序は何だと思いますか? Control InvokeとBeginInvokeは、メインスレッドであるUIスレッドで実行されることに注意してください。
A ----------------> B ----------------> C注意してください。これは参照用です。 。 。 。 。 、実行の順序がわかりません。専門家が知っている場合はお知らせください。
説明:

(1)UIスレッドでAが実行された後、BeginInvokeが開始され、BeginInvokeは非同期になります

これから、私たちは知っています:
ControlのInvokeおよびBeginInvokeのデリゲートメソッドは、メインスレッドであるUIスレッドで実行されます。つまり、デリゲートメソッドを使用して長時間のデータを取得してからインターフェイスなどを更新する場合は、UIスレッドでControl.InvokeとControl.BeginInvokeを呼び出さないでください。これらは、UIスレッドをブロックしているため、インターフェイスFalsedeath。

では、この非同期とはどういう意味ですか?

非同期とは、UIスレッドに関して非同期ではなく、BeginInvokeを呼び出すスレッドに関して非同期であることを指します。もちろん、UIスレッドでBeginInvokeを呼び出します。 ——————記事「InvokeとBeginInvokeの本当の意味」のコメントからの抜粋。
BeginInvokeの原則は、呼び出されたメソッドMarshalをメッセージに変換してから、Win32 APIでRegisterWindowMessage()を呼び出して、UIウィンドウにメッセージを送信することです。 ——————記事「InvokeとBeginInvokeの本当の意味」のコメントからの抜粋。




(2)、Threadを使用してBeginInvokeとInvokeを呼び出します
スレッドを開き、スレッドに時間のかかる操作を実行させてから、Control.InvokeとControl.BeginInvokeを使用してユーザーUIスレッドに戻り、インターフェイスの更新を実行します。

[コードⅢ]スレッドはControlInvokeを呼び出します

/ * Thread calls Invoke of Control * / private Thread invokeThread private delegate void invokeDelegate() private void StartMethod() { // C code segment ... Control.Invoke(new invokeDelegate(invokeMethod)) // D code segment ... } private void invokeMethod() { // E code segment } private void butInvoke_Click(object sender, EventArgs e) { // A code snippet ... invokeThread = new Thread(new ThreadStart(StartMethod)) invokeThread.Start() // B code segment ... }

コードの実行順序は何だと思いますか? Control InvokeとBeginInvokeは、メインスレッドであるUIスレッドで実行されることに注意してください。
A ------>(StartBとStartMethodCが同時に実行されます)---->(Cは終了し、Bが終了したかどうかに関係なく、invokeThreadはメッセージをUIスレッドにマーシャリングします。自分で待つ)----> butInvoke_Clickメッセージを処理した後、UIスレッドはinvokeThreadによってマーシャリングされたメッセージを処理し、invokeMethodメソッド、つまりコードセグメントEを実行してから、UIスレッドを処理してinvokeThreadスレッドに切り替えます。
このControl.Invokeは、invokeThreadスレッドと同期されているため、実行できません。

説明:
1.UI実行A
2. UIはスレッドInvokeThreadを開き、BとCは同時に実行され、BはスレッドUIで実行され、CはスレッドinvokeThreadで実行されます。
3. invokeThreadはメッセージをUIにマーシャリングしてから、それ自体を待ちます。 UIはメッセージを処理した後、invokeThreadによってマーシャリングされたメッセージ、つまりコードセグメントEを処理します。
4. UIがEを実行した後、スレッドinvokeThreadに移動し、invokeThreadスレッドがコードセグメントDを実行します。

[コードⅣ]スレッドはBeginInvokeofControlを呼び出します

/ * Thread calls BeginInvoke of Control * / private Thread beginInvokeThread private delegate void beginInvokeDelegate() private void StartMethod() { // C code segment ... Control.BeginInvoke(new beginInvokeDelegate(beginInvokeMethod)) // D code segment ... } private void beginInvokeMethod() { // E code segment } private void butBeginInvoke_Click(object sender, EventArgs e) { // A code snippet ... beginInvokeThread = new Thread(new ThreadStart(StartMethod)) beginInvokeThread .Start() // B code segment ... }

コードの実行順序は何だと思いますか? Control InvokeとBeginInvokeは、メインスレッドであるUIスレッドで実行されることに注意してください。
AはUIスレッドで実行されます-----> beginInvokeThreadスレッドは実行を開始し、UIはコードセグメントBを実行し続け、同時にinvokeThreadはコードセグメントCを実行します-------------- > UIが存在するかどうかに関係なく、コードセグメントBが実行された後、beginInvokeThreadスレッドはメッセージをUIにマーシャリングし、それを待ちません。実行を継続します--------> UIがbutBeginInvoke_Clickメッセージを処理した後、beginInvokeThreadスレッドマーシャルニュースを処理します。

説明:

(3)まとめ

コントロールのBeginInvokeは、それを呼び出したスレッドに関連しています。つまり、beginInvokeThreadは比較的非同期です。
したがって、私たちは考えることができます。データベースから大量のデータを読み取るなど、非同期で時間がかかるデータをフェッチする場合は、これを行う必要があります。
(1)スレッドの呼び出しを防ぎたい場合は、[コードIII]を呼び出すと、コードセグメントDが削除され、Cは別のスレッドで実行されるため、長時間実行操作に変更されます。インターフェイスを更新するためにコードセグメントEが変更されました。
(2)スレッドの呼び出しを阻止したくない場合は、[コードIV]を呼び出すと、コードセグメントDが削除され、Cは別のスレッドで実行されるため、長時間実行操作に変更されます。インターフェイスを更新するためにコードセグメントEが変更されました。

転載:https://www.cnblogs.com/asdyzh/p/9858794.html