2017-09-29 56 views
1

我有一个自托管的WCF服务,.NET框架4.5.2,使用NetTcpBinding和一个WPF客户端(4.5.2也)远程使用此服务。到目前为止,我所有的OperationContracts都是同步的。同步调用异步WCF方法无ServiceReference

我想添加一个异步的OperationContract到WCF服务,但是从客户端同步调用它(原因是这样我可以在服务方法中使用async/await)。

问题:此解决方案不使用服务引用或SvcUtil。我们使用共享库模式,其中服务合约是在客户端和服务器都参考的共享库中定义的。客户端代理使用ChannelFactory.CreateChannel创建。

这是否可行?我需要保持异步/等待出于客户端,但在服务器方法中使用它。如果这是不可能的,我可以使OperationContract同步,但将其视为Main方法并使用GetAwaiter()。GetResult(),否则会遇到死锁问题?

回答

0

不幸的是宣布你的服务器的OperationContract在您的服务合同装配创建不同的接口签名的3种独立的方式:

  • 平原同步FooResponse Foo(FooRequest)
  • APM异步IAsyncResult BeginFoo(FooRequest)/FooResponse EndFoo(IAsyncResult)
  • TAP异步Task<FooResponse> FooAsync(FooRequest)

但是,WCF对待他们电线上的所有相同“。 添加服务引用能够自动将ServiceContract转换为支持客户端所需样式的副本(在reference.cs中)。

在你的情况,如果你刚换的服务器使用TAP异步,客户端代码将不得不改变使用.Wait() \ .Result也许有些.ConfigureAwait(false)取决于应用程序。

随着一些提示从this answer还有一个更简单的方法:

  • 保留当前的同步服务合同
  • 创建整个服务合同的一个新的异步版本<Name>Async但保持相同的服务合同属性和操作
  • 将所有操作方法切换为FooAsync以上风格
  • 指定ServiceContact.Name与旧服务合同相同如果姓名被隐
  • 更改服务器来实现Async版本的服务合同的不同步一个

那么您的客户可以继续使用原来的同步接口聊到旧的或新的服务器。