技術共有

C# 非同期プログラミング Invoke、beginInvoke、endInvoke の使用法と関数

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

C# 非同期プログラミング Invoke、beginInvoke、endInvoke の使用法と関数

1. 呼び出す

Invoke の本質は単なるメソッドであり、メソッドはオブジェクトを通じて呼び出す必要があります。

一般に、Invoke が実際に使用される状況は 2 つだけです。

ControlInvoke

デリゲート呼び出し

つまり、Invoke の前にコントロール オブジェクトまたはデリゲート オブジェクトが置かれます。

ControlInvoke

コントロールの Invoke は通常、クロススレッド アクセスの問題を解決するために使用されます。たとえば、ボタンを操作したい場合は、button.Invoke を使用する必要があります。テキスト ラベルを操作したい場合は、label.Invoke を使用する必要があります。皆さんも大変だと思いますが、ボタンとラベルを両方操作したい場合は一緒に書いても良いでしょうか?もちろん。

メイン フォームは Form であることがわかっており、Form は当然 Control を継承するため、Form.Invoke を直接呼び出すことができる Invoke メソッドもあります。これは共通の this.Invoke です。これが、一部の Invoke の前に何もない理由です。実際には、これが省略されています。

例:

this.Invoke(new Action(() =>{ button1.Text = "关闭";}));

デリゲート呼び出し

デリゲートの Invoke は、実際には実行のためにスレッド プールからデリゲート メソッドを呼び出します。Invoke は同期メソッドであり、それを呼び出す UI スレッドをブロックします。

  1. void PrintMessage(string message) 
  2.     { 
  3.         Console.WriteLine(message); 
  4.     } 
  5.     MyDelegate myDelegate = PrintMessage; 
  6.     myDelegate.Invoke("Hello, World!"); // 使用 Invoke 方法调用委托引用的方法`

呼び出し開始、呼び出し終了

C# には、async/await、BackGroudWorker クラス、TPL (タスク並列ライブラリ) が存在することはすでにわかっています。もちろん、C# には非同期プログラミングをサポートする古いパターンがまだいくつかあります。

  1.     delegate long MyDel(int first, int second);
  2.     
  3.     class Program
  4.     {
  5.         static long Sum(int x, int y)
  6.         {
  7.             Console.WriteLine("------Inside Sum@{0}", DateTime.Now.ToString());
  8.             Thread.Sleep(2000);
  9.             return x + y;
  10.         }
  11.     
  12.         static void Main(string[] args)
  13.         {
  14.             MyDel del = new MyDel(Sum);
  15.     
  16.             Console.WriteLine("Before BeginInvoke---@{0}", DateTime.Now.ToString());
  17.             IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
  18.             Console.WriteLine("After BeginInvoke@{0}", DateTime.Now.ToString());
  19.     
  20.             Console.WriteLine("Doing stuff@{0}", DateTime.Now.ToString());
  21.     
  22.             long result = del.EndInvoke(iar);
  23.             Console.WriteLine("End Invoke@{0}", DateTime.Now.ToString());
  24.     
  25.             Console.WriteLine("After EndInvoke:  {0}", result);
  26.     
  27.             Console.ReadKey();
  28.     
  29.         }
  30.     }

上記のコードはデリゲート MyDel を定義し、呼び出されたときに Sum メソッドをそのオブジェクトに渡します。通常、このデリゲート オブジェクトを呼び出すと、その呼び出しリストに含まれるメソッドが呼び出されます。メソッドの呼び出しと同様に、これは同期的に行われます。

ただし、デリゲート オブジェクトの呼び出しリストにメソッド (参照メソッド) が 1 つだけある場合は、このメソッドを非同期で実行できます。 これを行うには、BeginInovke と EndInvoke を使用します。次のような方法で使用できます。

※ ① BeginInvoke メソッドを呼び出すと、独立したスレッドで参照メソッドの実行を開始し、すぐに元のスレッドに戻ります。元のスレッドは続行でき、参照メソッドは目的のスレッドで並行して実行されます。
* ② プログラムが完了した非同期メソッドの結果を取得したい場合、BeginInvoke から返される IAsyncResult の IsCompleted プロパティを確認するか、デリゲートの EndInvoke メソッドを呼び出してデリゲートの実行の完了を待ちます。

上記の使用プロセスは、次の 3 つのモードにつながります。

* ①完了まで待機します。元のスレッドが非同期メソッドを開始し、他の処理を実行した後、元のスレッドは中断し、非同期メソッドが完了するのを待ってから続行します。

* ②ポーリング。元のスレッドは、開始されたスレッドが完了したかどうかを定期的に確認します。完了していない場合は、他の作業を続行できます。

* ③ コールバックの元のスレッドは、開始スレッドでの参照発行が完了した後、待機や確認を行わずに常に実行され、開始スレッドはコールバック メソッドを呼び出し、コールバック メソッドは結果を処理します。 EndInvoke を呼び出す前に非同期メソッドを実行します。

参考サイト:

C#_C# Tutorial_Script Home での Invoke と BeginInvoke の実践的なアプリケーションの詳細な説明

C# スレッド デリゲート BeginInvoke と EndInvoke の使用法_C# Tutorial_Script ホーム