Как использовать службы на основе REST асинхронно с WCF? - PullRequest
1 голос
/ 27 июля 2011

Я хочу создать прокси-класс, который поддерживает асинхронные операции с сервисом на основе 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);
    }
}

(эта техника взята из этой статьи )

Существует ли аналогично простой способзаставить прокси поддерживать асинхронные операции (шаблоны BeginAction / EndAction или ActionAsync)?Или лучше всего свернуть мой метод вручную?

Обратите внимание, что я не могу добавить ссылку на службу в Visual Studio, так как нет доступных метаданных.

1 Ответ

3 голосов
/ 27 июля 2011

Если вы замените договор операции соответствующей парой «Начало / Конец», он должен работать и для договоров на основе 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();
    }
}
...