Como: implementar uma operação de serviço assíncrona
Em aplicativos WCF (Windows Communication Foundation), uma operação de serviço pode ser implementada de forma assíncrona ou síncrona sem determinar como o cliente deve chamá-la. Por exemplo, as operações de serviço assíncronas podem ser chamadas de forma síncrona e as operações de serviço síncronas podem ser chamadas de forma assíncrona. Para obter um exemplo que mostra como chamar uma operação de forma assíncrona em um aplicativo cliente, consulte Como chamar operações de serviço de forma assíncrona. Para obter mais informações sobre operações síncronas e assíncronas, consulte Como criar contratos de serviço e Operações síncronas e assíncronas. Este tópico descreve a estrutura básica de uma operação de serviço assíncrona, o código não está concluído. Para obter um exemplo completo do lado do serviço e do lado do cliente, consulte Assíncrono.
Implementar uma operação de serviço assíncrona
Em seu contrato de serviço, declare um par de métodos assíncronos de acordo com as diretrizes de design assíncronas do .NET. O método
Begin
usa um parâmetro, um objeto de retorno de chamada e um objeto de estado e retorna um System.IAsyncResult e um método correspondenteEnd
que usa um System.IAsyncResult e retorna o valor de retorno. Para obter mais informações sobre chamadas assíncronas, consulte Padrões de Design de Programação Assíncrona.Marque o método
Begin
do par de métodos assíncronos com o atributo System.ServiceModel.OperationContractAttribute e defina a propriedade OperationContractAttribute.AsyncPattern comotrue
. Por exemplo, o código a seguir executa as etapas 1 e 2.[OperationContractAttribute(AsyncPattern=true)] IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState); // Note: There is no OperationContractAttribute for the end method. string EndServiceAsyncMethod(IAsyncResult result); }
<OperationContractAttribute(AsyncPattern:=True)> _ Function BeginServiceAsyncMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult ' Note: There is no OperationContractAttribute for the end method. Function EndServiceAsyncMethod(ByVal result As IAsyncResult) As String End Interface
Implemente o par de métodos
Begin/End
em sua classe de serviço de acordo com as diretrizes de design assíncronas. Por exemplo, o pedaço de código a seguir mostra uma implementação na qual uma cadeia de caracteres é gravada no console nas partesBegin
eEnd
da operação de serviço assíncrona e o valor de retorno da operaçãoEnd
é retornado ao cliente. Para obter o exemplo de código completo, consulte a seção Exemplo.public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState) { Console.WriteLine("BeginServiceAsyncMethod called with: \"{0}\"", msg); return new CompletedAsyncResult<string>(msg); } public string EndServiceAsyncMethod(IAsyncResult r) { CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>; Console.WriteLine("EndServiceAsyncMethod called with: \"{0}\"", result.Data); return result.Data; }
Public Function BeginServiceAsyncMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult Implements ISampleService.BeginServiceAsyncMethod Console.WriteLine("BeginServiceAsyncMethod called with: ""{0}""", msg) Return New CompletedAsyncResult(Of String)(msg) End Function Public Function EndServiceAsyncMethod(ByVal r As IAsyncResult) As String Implements ISampleService.EndServiceAsyncMethod Dim result As CompletedAsyncResult(Of String) = TryCast(r, CompletedAsyncResult(Of String)) Console.WriteLine("EndServiceAsyncMethod called with: ""{0}""", result.Data) Return result.Data End Function
Exemplo
Os exemplos de código a seguir mostram:
Uma interface de contrato de serviço com:
Uma operação síncrona
SampleMethod
.Uma operação assíncrona
BeginSampleMethod
.Um par de operações assíncronas
BeginServiceAsyncMethod
/EndServiceAsyncMethod
.
Uma implementação de serviço usando um objeto System.IAsyncResult.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using System.Threading;
namespace Microsoft.WCF.Documentation
{
[ServiceContractAttribute(Namespace="http://microsoft.wcf.documentation")]
public interface ISampleService{
[OperationContractAttribute]
string SampleMethod(string msg);
[OperationContractAttribute(AsyncPattern = true)]
IAsyncResult BeginSampleMethod(string msg, AsyncCallback callback, object asyncState);
//Note: There is no OperationContractAttribute for the end method.
string EndSampleMethod(IAsyncResult result);
[OperationContractAttribute(AsyncPattern=true)]
IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState);
// Note: There is no OperationContractAttribute for the end method.
string EndServiceAsyncMethod(IAsyncResult result);
}
public class SampleService : ISampleService
{
#region ISampleService Members
public string SampleMethod(string msg)
{
Console.WriteLine("Called synchronous sample method with \"{0}\"", msg);
return "The synchronous service greets you: " + msg;
}
// This asynchronously implemented operation is never called because
// there is a synchronous version of the same method.
public IAsyncResult BeginSampleMethod(string msg, AsyncCallback callback, object asyncState)
{
Console.WriteLine("BeginSampleMethod called with: " + msg);
return new CompletedAsyncResult<string>(msg);
}
public string EndSampleMethod(IAsyncResult r)
{
CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>;
Console.WriteLine("EndSampleMethod called with: " + result.Data);
return result.Data;
}
public IAsyncResult BeginServiceAsyncMethod(string msg, AsyncCallback callback, object asyncState)
{
Console.WriteLine("BeginServiceAsyncMethod called with: \"{0}\"", msg);
return new CompletedAsyncResult<string>(msg);
}
public string EndServiceAsyncMethod(IAsyncResult r)
{
CompletedAsyncResult<string> result = r as CompletedAsyncResult<string>;
Console.WriteLine("EndServiceAsyncMethod called with: \"{0}\"", result.Data);
return result.Data;
}
#endregion
}
// Simple async result implementation.
class CompletedAsyncResult<T> : IAsyncResult
{
T data;
public CompletedAsyncResult(T data)
{ this.data = data; }
public T Data
{ get { return data; } }
#region IAsyncResult Members
public object AsyncState
{ get { return (object)data; } }
public WaitHandle AsyncWaitHandle
{ get { throw new Exception("The method or operation is not implemented."); } }
public bool CompletedSynchronously
{ get { return true; } }
public bool IsCompleted
{ get { return true; } }
#endregion
}
}
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.Text
Imports System.Threading
Namespace Microsoft.WCF.Documentation
<ServiceContractAttribute(Namespace:="http://microsoft.wcf.documentation")> _
Public Interface ISampleService
<OperationContractAttribute> _
Function SampleMethod(ByVal msg As String) As String
<OperationContractAttribute(AsyncPattern:=True)> _
Function BeginSampleMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult
'Note: There is no OperationContractAttribute for the end method.
Function EndSampleMethod(ByVal result As IAsyncResult) As String
<OperationContractAttribute(AsyncPattern:=True)> _
Function BeginServiceAsyncMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult
' Note: There is no OperationContractAttribute for the end method.
Function EndServiceAsyncMethod(ByVal result As IAsyncResult) As String
End Interface
Public Class SampleService
Implements ISampleService
#Region "ISampleService Members"
Public Function SampleMethod(ByVal msg As String) As String Implements ISampleService.SampleMethod
Console.WriteLine("Called synchronous sample method with ""{0}""", msg)
Return "The synchronous service greets you: " & msg
End Function
' This asynchronously implemented operation is never called because
' there is a synchronous version of the same method.
Public Function BeginSampleMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult Implements ISampleService.BeginSampleMethod
Console.WriteLine("BeginSampleMethod called with: " & msg)
Return New CompletedAsyncResult(Of String)(msg)
End Function
Public Function EndSampleMethod(ByVal r As IAsyncResult) As String Implements ISampleService.EndSampleMethod
Dim result As CompletedAsyncResult(Of String) = TryCast(r, CompletedAsyncResult(Of String))
Console.WriteLine("EndSampleMethod called with: " & result.Data)
Return result.Data
End Function
Public Function BeginServiceAsyncMethod(ByVal msg As String, ByVal callback As AsyncCallback, ByVal asyncState As Object) As IAsyncResult Implements ISampleService.BeginServiceAsyncMethod
Console.WriteLine("BeginServiceAsyncMethod called with: ""{0}""", msg)
Return New CompletedAsyncResult(Of String)(msg)
End Function
Public Function EndServiceAsyncMethod(ByVal r As IAsyncResult) As String Implements ISampleService.EndServiceAsyncMethod
Dim result As CompletedAsyncResult(Of String) = TryCast(r, CompletedAsyncResult(Of String))
Console.WriteLine("EndServiceAsyncMethod called with: ""{0}""", result.Data)
Return result.Data
End Function
#End Region
End Class
' Simple async result implementation.
Friend Class CompletedAsyncResult(Of T)
Implements IAsyncResult
Private data_Renamed As T
Public Sub New(ByVal data As T)
Me.data_Renamed = data
End Sub
Public ReadOnly Property Data() As T
Get
Return data_Renamed
End Get
End Property
#Region "IAsyncResult Members"
Public ReadOnly Property AsyncState() As Object Implements IAsyncResult.AsyncState
Get
Return CObj(data_Renamed)
End Get
End Property
Public ReadOnly Property AsyncWaitHandle() As WaitHandle Implements IAsyncResult.AsyncWaitHandle
Get
Throw New Exception("The method or operation is not implemented.")
End Get
End Property
Public ReadOnly Property CompletedSynchronously() As Boolean Implements IAsyncResult.CompletedSynchronously
Get
Return True
End Get
End Property
Public ReadOnly Property IsCompleted() As Boolean Implements IAsyncResult.IsCompleted
Get
Return True
End Get
End Property
#End Region
End Class
End Namespace