A chamar assincronamente um método do Visual C#

Traduções de Artigos Traduções de Artigos
Artigo: 315582 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

O Microsoft .NET Framework torna mais fácil chamar funções assincronamente. Chamar funções de forma assíncrona faz com que o sistema a executar em segundo plano num thread secundário enquanto a função chamada continua a executar qualquer outro trabalho. Numa chamada função (síncrona) normal, a função é executada imediatamente no mesmo thread que efectuou a chamada. A função chamada aguarda que a chamada para concluir e recebe os resultados da chamada antes de continuar. Por outro lado, quando fizer uma chamada assíncrona, obter os resultados da chamada assíncrona mais tarde. Este artigo demonstra como efectuar este procedimento utilizando o Visual C#.

Requisitos


A lista seguinte descreve o hardware recomendado, software, infra-estrutura de rede e service packs são necessários:
  • Microsoft Windows 2000 ou Microsoft Windows XP ou Microsoft Windows Server 2003
  • Visual Studio .NET ou Visual Studio 2005
Este artigo pressupõe que está familiarizado com os seguintes tópicos:
  • Chamar métodos no Visual C#
  • Como utilizar delegados

Como efectuar chamadas assíncronas

São efectuadas chamadas assíncronas utilizando delegados. Um delegado é um objecto que molda-se uma função. Os delegados fornecem uma função síncrona e também fornecerem métodos para chamar a função moldada assincronamente. Esses métodos são BeginInvoke() e EndInvoke() . As listas de parâmetro destes métodos variam consoante a assinatura da função que o delegado é moldado. Tenha em atenção que o Visual Studio .NET IntelliSense funcionalidade não apresenta BeginInvoke() e EndInvoke() , para que vê-los aparecer no não a função de lista à medida que escreve.

BeginInvoke() é utilizado para iniciar a chamada assíncrona. Tem os mesmos parâmetros como a função moldado além dois parâmetros adicionais que irão ser descritos neste artigo. BeginInvoke() devolve imediatamente e não aguarda que a chamada assíncrona para concluir. BeginInvoke() devolve um objecto IAsyncResult .

A função EndInvoke() é utilizada para obter os resultados da chamada assíncrona. Pode ser chamado em qualquer altura após BeginInvoke() . Se a chamada assíncrona não concluiu ainda, EndInvoke() blocos até que termine. Os parâmetros de função EndInvoke() inclui a out e parâmetros de ref com a função moldada e o objecto IAsyncResult devolvido pelo BeginInvoke() .

Segue-se um exemplo de um delegado e respectivos métodos BeginInvoke() e 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) ;
				
são quatro formas comuns de utilizar BeginInvoke() e EndInvoke() para efectuar chamadas assíncronas. Depois de chamar BeginInvoke() , pode:
  • Opcionalmente efectue algum trabalho e, em seguida, utilizar EndInvoke() .
  • Obter um WaitHandle fornecido pelo objecto IAsyncResult , utilize o método WaitOne para bloquear até WaitHandle é assinalado e, em seguida, chamar EndInvoke() .
  • Consultar o objecto IAsyncResult para determinar quando a chamada assíncrona foi concluída e, em seguida, chamar EndInvoke() .
  • Tem o sistema chamar uma função de chamada de retorno que especificar. Esta função de chamada de retorno chama EndInvoke() e processa os resultados da chamada assíncrona quando concluir.
Os seguintes exemplos de código demonstram estes padrões de chamada e contrastam-las com uma chamada síncrona utilizando a seguinte função:
string LongRunningMethod (int iCallTime, out int iExecThread)
{
	Thread.Sleep (iCallTime) ;
	iExecThread = AppDomain.GetCurrentThreadId ();
	return "MyCallTime was " + iCallTime.ToString() ;
}

				
LongRunningMethod() simula uma função que é executado para muito tempo, no modo de suspensão. Devolve a hora de suspensão e o ID do thread que executa. Se chamar assincronamente, descobrir de que o ID de thread do thread de execução é diferente do que o thread de chamada.

O primeiro passo consiste em definir o delegado molda-se a função:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;
				

Exemplo 1: Um método de chamada síncrona

Este exemplo demonstra como chamada síncrona LongRunningMethod() utilizando um delegado MethodDelegate . Os exemplos contrastam este efectuar chamadas de forma assíncrona.
  1. Inicie o Microsoft Visual Studio .NET ou Microsoft Visual Studio 2005.
  2. Crie um projecto aplicação do Visual C# consola de novo com o nome AsyncDemo.
  3. Adicionar uma classe denominada AsyncDemo é definida como se segue para o projecto num novo ficheiro .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() ) );
    	}
    }
    					
    mais tarde, esta classe demonstra como efectuar chamadas assíncronas. Inicialmente, no entanto, apenas contém o método DemoSyncCall() , que demonstra como chamada síncrona o delegado.
  4. Adicione o seguinte código no corpo da função principal que o Visual Studio cria automaticamente no projecto:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoSyncCall() ;
    }
    					
  5. Prima CTRL + F5 para executar a aplicação.

Exemplo 2: Chamada um método de forma assíncrona utilizando o padrão de EndInvoke() chamada

Nesta secção, o exemplo invoca o mesmo método de modo assíncrono. O padrão de chamada que é utilizado é chamar BeginInvoke , efectue algumas trabalhar no thread principal e, em seguida, chamar EndInvoke() . Tenha em atenção que EndInvoke() não devolve até que a chamada assíncrona foi concluída. Este padrão de chamada é útil quando pretende que o thread de chamada funcionam ao mesmo tempo que a chamada assíncrona está em execução. Ter trabalho ocorrer ao mesmo tempo, pode melhorar o desempenho de muitas aplicações. Tarefas comuns para serem executadas assincronamente desta forma são operações de ficheiro ou na rede.
  1. Adicione um método chamado DemoEndInvoke() à classe AsyncDemo . A função DemoEndInvoke demonstra como chamar assincronamente o delegado.
    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. Edite o código origem para principal para que contenha o seguinte código:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoEndInvoke() ;
    }
    					
  3. Prima CTRL + F5 para executar a aplicação.

Exemplo 3: Chamada de método de forma assíncrona e utilizar um WaitHandle para aguardar a chamada para concluir


Nesta secção, o exemplo chama o método de forma assíncrona e aguarda um WaitHandle antes de que chama EndInvoke() . O IAsyncResult devolvido pelo BeginInvoke() tem uma propriedade AsyncWaitHandle . Esta propriedade devolve um WaitHandle é assinalado quando concluir a chamada assíncrona. A aguardar um WaitHandle é uma comuns técnica de sincronização do thread. O thread chamado aguarda no WaitHandle utilizando o método WaitOne() de WaitHandle . blocos de WaitOne() até WaitHandle é assinalado. Quando devolve WaitOne() , pode efectuar algum trabalho adicional antes de telefonar EndInvoke() . Como no exemplo anterior, esta técnica é útil para executar operações de ficheiro ou de rede que caso contrário, bloquearia o thread principal chamado.
  1. Adicione uma função denominada DemoWaitHandle() para a classe AsyncDemo . A função DemoWaitHandle() demonstra como chamar assincronamente o delegado.
    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. Edite o código origem para principal para que contenha o seguinte código:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoWaitHandle () ;
    }
    					
  3. Prima CTRL + F5 para executar a aplicação.

Exemplo 4: Chamada de método de forma assíncrona utilizando o padrão de chamada de consulta

Nesta secção, o exemplo de consulta o objecto IAsyncResult para saber quando tiver concluído a chamada assíncrona. O objecto IAsyncResult devolvido pelo BeginInvoke() tem uma propriedade IsCompleted que devolve true depois de concluir a chamada assíncrona. Em seguida, é possível chamar EndInvoke() . Este padrão de chamada é útil se a aplicação funciona em curso pretende ter bloqueado por uma chamada de função de execução longa. Uma aplicação do Microsoft Windows é um exemplo desta situação. O thread principal da aplicação Windows pode continuar a processar a intervenção do utilizador enquanto executa uma chamada assíncrona. Pode verificar periodicamente IsCompleted para ver se a chamada foi concluída. Chama EndInvoke quando IsCompleted devolve Verdadeiro . Porque EndInvoke() bloqueia até a operação assíncrona está concluída, a aplicação não chama-lo até que seja conhecido que a operação foi concluída.
  1. Adicione uma função denominada DemoPolling() para a classe AsyncDemo . A função DemoPolling() demonstra como chamar assincronamente o delegado e utilizar a consulta para ver se o processo estiver concluído.
    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. Edite o código de origem de principal . Substituir os conteúdos da função com o seguinte código:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoPolling () ;
    }
    					
  3. Prima CTRL + F5 para executar a aplicação.

Exemplo 5: Executar uma chamada de retorno quando conclui um método assíncrono

Nesta secção, o exemplo fornece um delegado de chamada de retorno para a função BeginInvoke() que o sistema executa quando concluir a chamada assíncrona. A chamada de retorno chama EndInvoke() e processa os resultados da chamada assíncrona. Este padrão de chamada é útil se o thread que inicia a chamada assíncrona não é necessário processar os resultados da chamada. O sistema invoca a chamada de retorno num thread diferente do thread emitiu quando concluir a chamada assíncrona.

Para utilizar este padrão de chamada, tem de passar um delegado do tipo AsyncCallback como segundo ao último parâmetro da função BeginInvoke() . BeginInvoke() também tem um parâmetro final de escrever o objecto no qual pode passar qualquer objecto. Este objecto está disponível para a função de chamada de retorno quando é invocada. Uma utilização importante para este parâmetro deve passar o delegado é utilizado para iniciar a chamada. A função de chamada de retorno, em seguida, pode utilizar a função EndInvoke() desse delegado para concluir a chamada. Este padrão de chamada é demonstrado abaixo.
  1. Adicione um dois métodos denominados DemoCallback() e MyAsyncCallback() à classe AsyncDemo . O método DemoCallback() demonstra como chamar assincronamente o delegado. Utiliza um delegado para moldar o método MyAsyncCallback() , que o sistema chama quando concluir a operação assíncrona. MyAsyncCallback() chama 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. Edite o código de origem de principal . Substituir os conteúdos da função com o seguinte código:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoCallback() ;
    }
    					
  3. Prima CTRL + F5 para executar a aplicação.

Propriedades

Artigo: 315582 - Última revisão: 11 de dezembro de 2006 - Revisão: 4.3
A informação contida neste artigo aplica-se a:
  • Microsoft Visual Studio .NET 2002 Professional Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# 2005 Express Edition
Palavras-chave: 
kbmt kbhowtomaster KB315582 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 315582

Submeter comentários

 

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