6

我有一个遗留的 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 = trueOperationContract属性中删除 。
  • IAsyncResult返回类型替换void为接口和async void类中的。
  • 为了方便起见,删除 Begin/End 并添加 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();
4

1 回答 1

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使您能够等待发送实际消息(如果有延迟)并检测通道通信错误(如果您使用的是可靠通道)。

于 2013-03-13T13:15:54.000 回答