2013-03-13 3 views
6

У меня есть службы наследия WCF с рядом операционных контрактами One-Way, реализованных в наиболее классическом способе:Односторонний асинхронные/ждут звонков в WCF

// The interface 
    [OperationContract(IsOneWay = true, AsyncPattern = true)] 
    IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState); 
    void EndFinalizePublishing(IAsyncResult result); 

    // The service 
    public IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState) 
    {...} 

Так что все отлично работает здесь, теперь мне нужно чтобы преобразовать это в C# 5 последний шаблон async/await. Обратите внимание на одностороннюю природу операций. Мои вопросы:

  • Я думаю, мне нужно удалить AsyncPattern = true из атрибута OperationContract.
  • Замените тип возврата IAsyncResult с интерфейсом void и async void в классе.
  • Удалите начало/конец и добавьте постсинтез Async для удобства.

Теперь, как я могу назвать одностороннюю операцию с клиентом? Нет использования async/await на стороне клиента для односторонних вызовов?

Это правильно и приведет к истинной асинхронной обработке на стороне клиента.

// The proxy 
    public void FinalizePublishingAsync(PageContent pageContent) 
    { 
     Channel.FinalizePublishingAsync(pageContent); 
    } 

     // The consumer of the client 
     // No way to use await for void methods. 
     IComPublisherFinalizerClient cl = new IComPublisherFinalizerClient(); 
     cl.FinalizePublishingAsync(content); 
     cl.Close(); 

ответ

6

Во-первых, клиент полностью отделен от сервера. Любой клиент или сервер может быть синхронным, использовать асинхронный код IAsyncResult (APM) или использовать асинхронный код async (TAP).

Во-вторых, методы async на стороне сервера должны возвращать Task, даже для односторонней связи. async эквивалент синхронного метода возврата void - это метод async Task, а не метод async void. async void особенно опасен в службах WCF, поскольку он может нарушать ConcurrencyMode.

Так что ваши серверные шаги будут выглядеть следующим образом:

  • Удалить OperationContract.AsyncPattern.
  • Объединить метод метода Begin*/End* в один метод *Async, который возвращает Task.

Ваша сторона клиент должен увидеть Task методы -returning на интерфейсе для его прокси, который он должен await. Это не означает, что вы ожидаете ответа; этот await позволяет дождаться отправки фактического сообщения (если есть задержки) и обнаружить ошибки связи канала (если вы используете надежный канал).

+0

Stephen, Спасибо за ответ. Односторонние вызовы не имеют ответного сообщения и ожидаются до тех пор, пока сервер не получит запрос - именно поэтому они помечены как пустота. Но, как я знаю (Juval пишет об этом), сервер действительно отправляет короткий ответ msg, говорящий, что запрос клиента поставлен в очередь. IAsyncResult решает эту проблему. И вы хотите сказать, что хотя операция (отмеченная как OneWay) возвращает задание, вызывающий не будет заблокирован до ответа сервера? Или он будет действовать как обычная операция OneWay блокировки до ответа серверов? – Zara

+0

Он будет действовать как обычная операция OneWay. Поэтому он не будет дожидаться завершения (или вызванного) метода сервера и не будет сообщать об ошибках с сервера. –

Смежные вопросы