Обмен технологиями

Асинхронное программирование на C#. Использование и функции Invoke, BeginInvoke, endInvoke.

2024-07-12

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

Асинхронное программирование на C#. Использование и функции Invoke, BeginInvoke, endInvoke.

1. Вызов

Суть Invoke — это всего лишь метод, и метод должен вызываться через объект.

Вообще говоря, есть только две ситуации, когда Invoke действительно используется:

ControlInvoke

ДелегатИнвоке

Другими словами, Invoke предшествует либо элемент управления, либо объект делегата.

ControlInvoke

Invoke элемента управления обычно используется для решения проблем межпоточного доступа. Например, если вы хотите управлять кнопкой, вам нужно использовать button.Invoke. Если вы хотите управлять текстовой меткой, вам нужно использовать label.Invoke, но. всем это будет очень хлопотно. Если я хочу использовать и кнопку, и метку, могу ли я написать их вместе? конечно.

Мы знаем, что основная форма — это Form, а Form естественным образом наследует Control, поэтому у Form также есть метод Invoke, который может напрямую вызывать Form.Invoke. Это наш общий this.Invoke. Вот почему перед некоторыми Invokes ничего нет. На самом деле перед ними есть это, но оно опущено.

Пример:

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

ДелегатИнвоке

Invoke делегата фактически вызывает метод делегата из пула потоков для выполнения. Invoke является синхронным методом и блокирует вызывающий его поток пользовательского интерфейса.

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

beginInvoke, endInvoke

Мы уже знаем, что в 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 его объекту при вызове. Обычно, когда мы вызываем этот объект делегата, он вызывает методы, включенные в его список вызовов. Как и вызов метода, это делается синхронно.

Но если объект делегата имеет в списке вызовов только один метод (ссылочный метод), он может выполнить этот метод асинхронно. Для этого используются BeginInovke и EndInvoke. Мы можем использовать его следующим образом:

* ① Когда мы вызываем метод BeginInvoke, он начинает выполнение ссылочного метода в независимом потоке и немедленно возвращается в исходный поток. Исходный поток может продолжаться, и эталонный метод будет выполняться параллельно в нужном потоке.
* ② Когда программа хочет получить результат завершенного асинхронного метода, она может проверить свойство IsCompleted IAsyncResult, возвращаемого BeginInvoke, или вызвать метод EndInvoke делегата, чтобы дождаться завершения выполнения делегата.

Вышеописанный процесс использования приводит к трем режимам:

* ① Ожидание завершения. После того, как исходный поток инициирует асинхронный метод и выполняет какую-либо другую обработку, исходный поток прерывается и ждет завершения асинхронного метода, прежде чем продолжить.

* ②Опрос: исходный поток регулярно проверяет, завершен ли инициированный поток. Если нет, он может продолжать выполнять другие действия.

* ③ Исходный поток обратного вызова всегда выполняется без ожидания или проверки завершения инициирующего потока. После завершения выдачи ссылки в инициирующем потоке инициирующий поток вызывает метод обратного вызова, а метод обратного вызова обрабатывает результат. асинхронного метода перед вызовом EndInvoke.

Справочный сайт:

Подробное объяснение практического применения Invoke и BeginInvoke в C#_C# Tutorial_Script Home

Использование делегата потока C# BeginInvoke и EndInvoke_C# Tutorial_Script