Share via


How to: Implement an Asynchronous Service Operation

In Windows Communication Foundation (WCF) applications, a service operation can be implemented asynchronously or synchronously without dictating to the client how to call it. For example, asynchronous service operations can be calling synchronously, and synchronous service operations can be called asynchronously. For an example that shows how to call an operation asynchronously in a client application, see How to: Call WCF Service Operations Asynchronously. For more information about synchronous and asynchronous operations, see Designing Service Contracts and Synchronous and Asynchronous Operations.

Implement a service operation asynchronously

  1. In your service contract, declare an asynchronous method pair according to the .NET asynchronous design guidelines. The Begin method takes a parameter, a callback object, and a state object, and returns a System.IAsyncResult and a matching End method that takes a System.IAsyncResult and returns the return value. For more information about asynchronous calls, see Asynchronous Programming Design Patterns.

  2. Mark the Begin method of the asynchronous method pair with the System.ServiceModel.OperationContractAttribute attribute and set the System.ServiceModel.OperationContractAttribute.AsyncPattern property to true. For example, the following code performs steps 1 and 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);
    }
    
  3. Implement the Begin/End method pair in your service class according to the asynchronous design guidelines. For example, the following code example shows an implementation in which a string is written to the console in both the Begin and End portions of the asynchronous service operation, and the return value of the End operation is returned to the client. For the complete code example, see the Example section.

Example

The following code examples show:

  1. A service contract interface with:

    1. A synchronous SampleMethod operation.

    2. An asynchronous BeginSampleMethod operation.

    3. An asynchronous BeginServiceAsyncMethod/EndServiceAsyncMethod operation pair.

  2. A service implementation using a System.IAsyncResult object.

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 sychronous 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
  }
}

See Also

Concepts

Designing Service Contracts
Synchronous and Asynchronous Operations


© 2007 Microsoft Corporation. All rights reserved.
Build Date: 2009-08-07