我有一个传统的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 / 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();
答案 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
使您可以等待发送实际消息(如果有延迟)并检测通道通信错误(如果您使用的是可靠通道)。