如何与WCF异步使用基于REST的服务?

时间:2011-07-27 14:38:19

标签: c# wcf rest asynchronous wcf-client

我想创建一个代理类,支持针对基于REST的服务的异步操作。

为了便于讨论,我们假设我有一项服务IService

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebGet(UriTemplate = "{a}/{b}")]
    void Action(string a, string b);
}

我可以使用:

轻松创建同步代理类
class Client: ClientBase<IService>, IService
{
    public void Action(string a, string b)
    {
        Channel.Action(a, b);
    }
}

(此技术来自此article

是否有类似的直接方式使代理支持异步操作(BeginAction / EndActionActionAsync模式)?或者是手动滚动自己的最佳做法?

请注意,我无法在Visual Studio中添加服务引用,因为没有可用的元数据。

1 个答案:

答案 0 :(得分:3)

如果将操作合同替换为相应的Begin / End对,则它也适用于基于REST的合同。您甚至可以在客户端上具有两个同步和异步版本的操作(但在这种情况下,您只需要在同步版本上具有[WebGet]属性。)

public class StackOverflow_6846215
{
    [ServiceContract(Name = "ITest")]
    public interface ITest
    {
        [OperationContract]
        [WebGet]
        int Add(int x, int y);
    }
    [ServiceContract(Name = "ITest")]
    public interface ITestClient
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object state);
        int EndAdd(IAsyncResult asyncResult);

        [OperationContract]
        [WebGet]
        int Add(int x, int y);
    }
    public class Client : ClientBase<ITestClient>, ITestClient
    {
        public Client(string baseAddress)
            :base(new WebHttpBinding(), new EndpointAddress(baseAddress))
        {
            this.Endpoint.Behaviors.Add(new WebHttpBehavior());
        }

        public IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object state)
        {
            return this.Channel.BeginAdd(x, y, callback, state);
        }

        public int EndAdd(IAsyncResult asyncResult)
        {
            return this.Channel.EndAdd(asyncResult);
        }

        public int Add(int x, int y)
        {
            return this.Channel.Add(x, y);
        }
    }
    public class Service : ITest
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
        host.Open();
        Console.WriteLine("Host opened");

        Client client = new Client(baseAddress);
        Console.WriteLine("Sync result: {0}", client.Add(66, 77));
        client.BeginAdd(44, 55, delegate(IAsyncResult ar)
        {
            int result = client.EndAdd(ar);
            Console.WriteLine("Async result: {0}", result);
        }, null);

        Console.WriteLine("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}