В настоящее время вы работаете в автономном режиме; ожидается повторное подключение к Интернету

Как асинхронно вызвать метод C#

ВНИМАНИЕ! Данная статья переведена с использованием программного обеспечения Майкрософт для машинного перевода и, возможно, отредактирована посредством технологии Community Translation Framework (CTF). Корпорация Майкрософт предлагает вам статьи, обработанные средствами машинного перевода, отредактированные членами сообщества Майкрософт и переведенные профессиональными переводчиками, чтобы вы могли ознакомиться со всеми статьями нашей базы знаний на нескольких языках. Статьи, переведенные с использованием средств машинного перевода и отредактированные сообществом, могут содержать смысловое, синтаксические и (или) грамматические ошибки. Корпорация Майкрософт не несет ответственности за любые неточности, ошибки или ущерб, вызванные неправильным переводом контента или его использованием нашими клиентами. Подробнее об CTF можно узнать по адресу http://support.microsoft.com/gp/machine-translation-corrections/ru.

Эта статья на английском языке: 315582
Аннотация
Платформа.NET Framework Microsoft делает асинхронного вызова функции. Асинхронный вызов функций заставляет систему выполнять их в фоновом режиме во вторичном потоке, в то время, как функция вызова продолжает выполнять другую работу. В вызове функции обычной (синхронный) функция немедленно выполняется в том же потоке, который сделал звонок. Т.е. код, который вызвал синхронно функцию, ожидает её завершения перед тем как продолжить дальнейшее исполнение. И наоборот, при асинхронном вызове функции, результат её исполнения будет получен позже. В этой статье показано, как это сделать с помощью C#.

back to the top

Требования


В следующем списке представлены: рекомендуемое оборудование, программное обеспечение, сетевые требования и пакеты обновления, которые требуются:
  • Microsoft Windows 2000 или Microsoft Windows XP или Microsoft Windows Server 2003
  • Visual Studio .NET или Visual Studio 2005
Предполагается, что вы знакомы со следующими разделами:
  • Вызов методов в Visual C#
  • Использование делегатов
back to the top

Как создать асинхронные вызовы

Асинхронные вызовы выполняются с помощью делегатов. Делегат — это объект, который создает оболочку для функции. Делегаты синхронный функцию и также предоставляют методы для асинхронного вызова функции оболочку. Эти методы являются BeginInvoke() и EndInvoke(). Списки параметров этих методов зависят от подписи функции, этот делегат служит оболочкой. Обратите внимание, что функцию Visual Studio .NET IntelliSense не отображает BeginInvoke() и EndInvoke(), поэтому вы не видите в списках функции отображаются по мере ввода.

BeginInvoke() используется для инициирования асинхронного вызова. Он имеет те же параметры, как функцию-оболочку, а также два дополнительных параметра, которые будут описаны далее в этой статье. BeginInvoke() возвращает управление сразу, без ожидания завершения асинхронного вызова. BeginInvoke() возвращает объект IAsyncResult .

Функция EndInvoke() используется для получения результатов асинхронного вызова. Она может быть вызвана в любое время после BeginInvoke(). Если асинхронный вызов не завершен, EndInvoke() блокирует код до окончания асинхронного вызова. Включает параметры функции EndInvoke()Выход и ref параметры, которые имеет функцию-оболочку, плюс объекта IAsyncResult , возвращаемого BeginInvoke().

Ниже приведен пример делегата и его методы BeginInvoke() и EndInvoke() :
// The following delegate delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;// will have the following BeginInvoke() and EndInvoke methods:IAsyncResult MethodDelegate.BeginInvoke(int iCallTime, out int iExecThread, AsyncCallback cb, object AsyncState); string MethodDelegate.EndInvoke (out int iExecThread, IAsyncResult ar) ;				
Существует четыре основных способа использования BeginInvoke() и EndInvoke() для выполнения асинхронных вызовов. После вызова BeginInvoke(), вы можете:
  • При необходимости некоторых других действий, а затем с помощью EndInvoke().
  • Получения WaitHandle , который предоставляется с помощью объекта IAsyncResult , метод WaitOne для блокировки до момента WaitHandle выставляет сигнал и затем вызвать EndInvoke().
  • Опрос объект IAsyncResult для определения времени завершения асинхронного вызова, вызов andthen EndInvoke().
  • Система вызова функции обратного вызова, указанный. Этот вызов функции обратного вызова EndInvoke() и процессы результаты асинхронного вызова при itcompletes.
В следующих примерах кода демонстрируются эти вызова шаблонов и сравните их с синхронный вызов, используя следующие функции:
string LongRunningMethod (int iCallTime, out int iExecThread){	Thread.Sleep (iCallTime) ;	iExecThread = AppDomain.GetCurrentThreadId ();	return "MyCallTime was " + iCallTime.ToString() ;}				
LongRunningMethod() эмулирует функции, которая запускается в течение длительного времени в спящем режиме. Возвращает время ожидания и идентификатор потока, который ее выполняет. Если вызывается асинхронно, обнаружится, что идентификатор выполняемого потока отличается от вызывающего потока.

Первым шагом является определение делегата, который создает оболочку для функции:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;				

Пример 1: Вызов метода синхронно

В этом примере показано, как вызвать LongRunningMethod() синхронно с помощью делегата MethodDelegate . Другие примеры Сравните это путем вызова асинхронно.
  1. Запустите Microsoft Visual Studio .NET или Microsoft Visual Studio 2005.
  2. Создание нового приложения консоли Visual C# проекта namedAsyncDemo.
  3. Добавьте класс с именем AsyncDemo, определяется как для проекта в новый файл с расширением CS:
    using System;using System.Threading ; using System.Windows.Forms ;public class AsyncDemo{	string LongRunningMethod (int iCallTime, out int iExecThread)	{		Thread.Sleep (iCallTime) ;		iExecThread = AppDomain.GetCurrentThreadId ();		return "MyCallTime was " + iCallTime.ToString() ;	}	delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;	public void DemoSyncCall()	{		string s ;		int iExecThread;		// Create an instance of a delegate that wraps LongRunningMethod.		MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;  					// Call LongRunningMethod using the delegate.		s = dlgt(3000, out iExecThread);  					MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\",                                         and the thread ID {1}", s, iExecThread.ToString() ) );	}}					
    Позже этот класс демонстрирует для выполнения асинхронных вызовов. Изначально Однако он содержит только метод DemoSyncCall() , который демонстрирует вызов delegatesynchronously.
  4. Добавьте следующий код в теле функции Main , Visual Studio автоматически создает в Ваш_проект:
    static void Main(string[] args){	AsyncDemo ad = new AsyncDemo () ;	ad.DemoSyncCall() ;}					
  5. Нажмите сочетание клавиш CTRL + F5 для запуска приложения.
back to the top

Пример 2: Асинхронный вызов метода, используя шаблон вызова EndInvoke()

В этом разделе Пример асинхронно вызывает тот же метод. Вызов шаблон, который будет использоваться — вызов BeginInvoke, выполните некоторые работает в основном потоке, а затем вызвать EndInvoke(). Обратите внимание, что EndInvoke() не возвращается до завершения асинхронного вызова. Этот шаблон полезен, когда необходимо, чтобы вызывающий поток работал в то же время, когда исполняется асинхронные операции. Повышается производительность за счет одновременного исполнения разных работ. Как правило такие задачи служат для асинхронной работы с файлами или сетевыми операциями.
  1. Добавьте метод с именем DemoEndInvoke() в классе AsyncDemo . Функция DemoEndInvoke показано, как вызывать делегат асинхронно.
    public void DemoEndInvoke(){	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;	string s ;	int iExecThread;	// Initiate the asynchronous call.	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null);  	// Do some useful work here. This would be work you want to have	// run at the same time as the asynchronous call.	// Retrieve the results of the asynchronous call.	s = dlgt.EndInvoke (out iExecThread, ar) ;  	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\",                                and the number {1}", s, iExecThread.ToString() ) );}					
  2. Редактировать исходный код для основного , содержащий следующий код:
    static void Main(string[] args){	AsyncDemo ad = new AsyncDemo () ;	ad.DemoEndInvoke() ;}					
  3. Нажмите сочетание клавиш CTRL + F5 для запуска приложения.
back to the top

Пример 3: Асинхронный вызов метода с использованием WaitHandle для ожидания завершения вызова


В этом разделе пример вызывает метод асинхронно и ожидает WaitHandle , перед вызовом EndInvoke(). IAsyncResult , возвращаемого BeginInvoke() имеет свойство AsyncWaitHandle . Это свойство возвращает сигнал при завершении асинхронного вызова WaitHandle . Ожидание WaitHandle является распространенным способом синхронизации потоков. Вызывающий поток ожидает WaitHandle , используя метод WaitOne() класса WaitHandle. Пока WaitHandle выставляет сигнал WaitOne() блокирует вызывающий поток. При возвращении WaitOne() можно выполнить дополнительные действия перед вызовом EndInvoke(). Как и в предыдущем примере этот метод полезен для выполнения файла или сетевой операции, которые в противном случае будет блокировать вызывающий поток главного.
  1. Добавление функции с именем DemoWaitHandle() в классе AsyncDemo . Функция DemoWaitHandle() показано, как вызывать делегат асинхронно.
    public void DemoWaitHandle (){	string s ;	int iExecThread;	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;	// Initiate the asynchronous call.	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); 	// Do some useful work here. This would be work you want to have	// run at the same time as the asynchronous call.	// Wait for the WaitHandle to become signaled.	ar.AsyncWaitHandle.WaitOne() ;	// Get the results of the asynchronous call.	s = dlgt.EndInvoke (out iExecThread, ar) ;				MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\",                                  and the number {1}", s, iExecThread.ToString() ) );}					
  2. Редактировать исходный код для основного , содержащий следующий код:
    static void Main(string[] args){	AsyncDemo ad = new AsyncDemo () ;	ad.DemoWaitHandle () ;}					
  3. Нажмите сочетание клавиш CTRL + F5 для запуска приложения.
back to the top

Пример 4: Асинхронный вызов метода с помощью вызова шаблон опроса

В этом разделе Пример опрашивает объект IAsyncResult , чтобы определить, когда асинхронный вызов завершен. Объект IAsyncResult , который возвращается BeginInvoke() имеет свойство IsCompleted , которое возвращает значение True , после завершения асинхронного вызова. Затем можно вызвать EndInvoke(). Этот шаблон вызова полезен, если ваше приложение работает постоянно, не должен блокироваться с помощью вызова функции длительные. Приложение Microsoft Windows является примером этого. Основной поток приложения Windows можно продолжить обработки вводимых пользователем данных, когда выполняется асинхронный вызов. Он может периодически проверять IsCompleted для просмотра завершения вызова. Он вызывает Метод EndInvoke Если IsCompleted возвращает значение True. Поскольку EndInvoke() блокирует до момента завершения асинхронной операции, приложение не вызывает он пока не знает, что операция будет завершена.
  1. Добавление функции с именем DemoPolling() в классе AsyncDemo . Функция DemoPolling() показано, как вызывать делегат асинхронно опроса используйте для просмотра, если процесс завершен.
    public void DemoPolling(){	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;	string s ;	int iExecThread;	// Initiate the asynchronous call.	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); 	// Poll IAsyncResult.IsCompleted	while(ar.IsCompleted == false)	{		Thread.Sleep (10) ;  // pretend to so some useful work	}	s = dlgt.EndInvoke (out iExecThread, ar) ;	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\",                                 and the number {1}", s, iExecThread.ToString() ) );}					
  2. Редактирование исходного кода для основной. Замените содержимое функции следующий код:
    static void Main(string[] args){	AsyncDemo ad = new AsyncDemo () ;	ad.DemoPolling () ;}					
  3. Нажмите сочетание клавиш CTRL + F5 для запуска приложения.
back to the top

Пример 5: Выполнение обратного вызова при завершении асинхронного метода

В этом разделе пример предоставляет обратный вызов делегата для функции BeginInvoke() , система выполняет при завершении асинхронного вызова. Обратный вызов EndInvoke() и обрабатывает результаты асинхронного вызова. Этот шаблон вызова полезен в том случае, если поток, инициировавший асинхронный вызов не требуется обрабатывать результаты вызова. Система вызывает функцию обратного вызова в потоке, инициализирующий поток при завершении асинхронного вызова.

Чтобы использовать этот шаблон вызова, необходимо передать делегат AsyncCallback типа как второй с конца параметр функции BeginInvoke() . BeginInvoke() также имеет последний параметр тип объекта , в котором можно передать любой объект. Этот объект доступен для функции обратного вызова при его вызове. Одним из важных использования этого параметра является передать делегат, который используется для инициирования вызова. Функция обратного вызова затем можно использовать функцию EndInvoke() этот делегат для выполнения этого вызова. Этот шаблон вызова описана ниже.
  1. Добавьте два метода AsyncDemo класса с именем DemoCallback() и MyAsyncCallback() . Метод DemoCallback() показано, как вызывать делегат асинхронно. Ituses делегат для метода MyAsyncCallback() , который вызывается системой, когда асинхронный operationcompletes. MyAsyncCallback() вызывает EndInvoke().
    public void DemoCallback(){	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;	string s ;	int iExecThread;	// Create the callback delegate.	AsyncCallback cb = new AsyncCallback(MyAsyncCallback);	// Initiate the Asynchronous call passing in the callback delegate	// and the delegate object used to initiate the call.	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt); }public void MyAsyncCallback(IAsyncResult ar){	string s ;	int iExecThread ;	// Because you passed your original delegate in the asyncState parameter	// of the Begin call, you can get it back here to complete the call.	MethodDelegate dlgt = (MethodDelegate) ar.AsyncState;	// Complete the call.	s = dlgt.EndInvoke (out iExecThread, ar) ;	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\",                                 and the number {1}", s, iExecThread.ToString() ) );}					
  2. Редактирование исходного кода для основной. Замените содержимое функции следующий код:
    static void Main(string[] args){	AsyncDemo ad = new AsyncDemo () ;	ad.DemoCallback() ;}					
  3. Нажмите сочетание клавиш CTRL + F5 для запуска приложения.
back to the top

Внимание! Эта статья переведена автоматически

Свойства

Номер статьи: 315582 — последний просмотр: 05/23/2015 13:49:00 — редакция: 7.0

Microsoft Visual Studio .NET 2002 Professional Edition, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# 2005 Express Edition

  • kbhowtomaster kbmt KB315582 KbMtru
Отзывы и предложения