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

Переводы статьи Переводы статьи
Код статьи: 315582 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Аннотация

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

Требования


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

Как для выполнения асинхронных вызовов

Асинхронные вызовы выполняются с помощью делегатов. Делегат — Объект, который служит оболочкой для функции. Делегаты обеспечивают синхронное функции, а также предоставляют методы для асинхронного вызова оболочку функции. Эти методы — BeginInvoke() и EndInvoke(). Списки параметров эти методы различаются в зависимости от подпись функции, этот делегат служит оболочкой. Обратите внимание, что Visual Studio Функция IntelliSense .NET не отображает 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 , чтобы определить завершение асинхронного вызова, и Затем нужно вызовите EndInvoke().
  • Система вызова функции обратного вызова. Этот вызов функции обратного вызова EndInvoke() и процессы результаты асинхронного вызова при его Завершает процесс.
В следующих примерах кода демонстрируются эти вызов шаблонов и Сравните их с синхронный вызов, используя следующие функции:
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# с именем AsyncDemo.
  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() , который демонстрирует вызов делегата синхронно.
  4. Добавьте следующий код в теле функции Main , Visual Studio автоматически создает в вашем проект:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoSyncCall() ;
    }
    					
  5. Нажмите CTRL + F5 для запуска приложения.

Пример 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 для запуска приложения.

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


В этом разделе пример вызывает метод, асинхронно и ожидает WaitHandle перед вызовом EndInvoke(). IAsyncResult , возвращаемый BeginInvoke() имеет свойство AsyncWaitHandle . Это свойство возвращает WaitHandle , который отправляется сигнал при завершении асинхронного вызова. Ожидание WaitHandle является распространенным способом синхронизации потоков. Вызывающий поток ожидает WaitHandle , используя метод WaitOne()WaitHandle. Блоки WaitOne() до возникновения WaitHandle . При возвращении 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 для запуска приложения.

Образец 4: Асинхронный вызов метода, используя шаблон опроса звонок

В этом разделе примера опрашивает объект IAsyncResult , чтобы узнать, после завершения асинхронного вызова. Объект IAsyncResult , который возвращается BeginInvoke() имеет свойство IsCompleted , которое возвращает значение True после завершения асинхронного вызова. Затем можно вызвать EndInvoke(). Этот шаблон вызова полезен, если текущее приложение работа действительно хотите блокироваться с помощью вызова функции длительного выполнения. A Приложение 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 для запуска приложения.

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

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

Чтобы использовать этот шаблон вызова, необходимо передать делегат AsyncCallback типа как второй с конца параметр функции BeginInvoke() . BeginInvoke() также имеет последний параметр тип объекта , в который можно передать любой объект. Этот объект доступен для функции обратного вызова при его вызове. Одним из важных использования этого параметра Рекомендуется передать делегат, который используется для инициирования вызова. Обратный вызов функция затем можно использовать функцию EndInvoke() этот делегат для выполнения этого вызова. Этот шаблон вызова описана ниже.
  1. Добавьте два метода с именем DemoCallback() и MyAsyncCallback() к классу AsyncDemo . Метод DemoCallback() показано, как вызывать делегат асинхронно. Он использует делегат для обеспечения оболочки для метода MyAsyncCallback() , который вызывается системой, когда асинхронная операция Завершает процесс. 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 для запуска приложения.

Свойства

Код статьи: 315582 - Последний отзыв: 30 декабря 2012 г. - Revision: 6.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
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке: 315582

Отправить отзыв

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com