单向异步/等待WCF中的调用

时间:2013-03-13 12:55:54

标签: c# .net wcf async-await

我有一个传统的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();

1 个答案:

答案 0 :(得分:6)

首先,客户端完全独立于服务器。客户端或服务器可以是同步的,使用IAsyncResult(APM)异步代码,或使用async(TAP)异步代码。

其次,服务器端的async方法应该返回Task,即使是单向通信也是如此。返回async的同步方法的void等价物是async Task方法,而不是async void方法。 async void在WCF服务中尤其危险,因为它可能违反了ConcurrencyMode

因此,您的服务器端步骤将如下所示:

  • 删除OperationContract.AsyncPattern
  • Begin* / End*方法对合并为一个返回*Async的{​​{1}}方法。

您的客户端应该看到Task - 在其代理的接口上返回方法,它应该Task。这并不意味着你在等待回应;这个await使您可以等待发送实际消息(如果有延迟)并检测通道通信错误(如果您使用的是可靠通道)。