繁体   English   中英

在没有ServiceReference的情况下同步调用异步WCF方法

[英]Calling async WCF method synchronously WITHOUT ServiceReference

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

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

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

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

不幸的是,声明服务器的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)具体取决于应用程序。

此答案中得到一些提示, 是一种更简单的方法:

  • 保留当前的同步服务合同
  • 将整个服务合同的新异步版本创建为<Name>Async但保留相同的服务合同属性和操作
  • 将所有操作方法切换为上方的FooAsync样式
  • 如果名称隐式,则将ServiceContact.Name指定为与旧服务合同相同
  • 更改您的服务器以实现服务合同的Async版本,而不是同步的

然后,您的客户端可以继续使用与新旧服务器通信的原始同步接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM