我有一个自托管的WCF服务,.NET framework 4.5.2,使用NetTcpBinding,以及一个WPF客户端(4.5.2)也远程使用这个服务。到目前为止,我的所有OperationContracts都是同步的。
我想将一个异步OperationContract添加到WCF服务,但是从客户端同步调用它(原因是我可以在服务方法中使用async / await)。
catch:此解决方案不使用服务引用或SvcUtil。我们使用共享库模式,其中服务契约在客户端和服务器引用的共享库中定义。客户端代理是使用ChannelFactory.CreateChannel创建的。
这甚至可行吗?我需要保持async / await不在客户端,但在服务器方法中使用它。如果不可能,我可以将OperationContract同步,但将其视为Main方法并使用GetAwaiter()。GetResult(),还是会遇到死锁问题?
答案 0 :(得分:0)
不幸的是,声明服务器OperationContract
的3种不同方式在服务合同程序集中创建了不同的界面签名:
FooResponse Foo(FooRequest)
IAsyncResult BeginFoo(FooRequest)
/ FooResponse EndFoo(IAsyncResult)
Task<FooResponse> FooAsync(FooRequest)
然而,WCF“在线上”对待这些都是相同的。
添加服务引用能够自动将ServiceContract
转换为支持客户端所需样式的副本(在reference.cs中)。
在您的情况下,如果您只是将服务器切换为使用TAP异步,则客户端代码必须更改为使用.Wait()
\ .Result
,可能还需要一些.ConfigureAwait(false)
,具体取决于应用
通过this answer的一些提示,有一种更简单的方法:
<Name>Async
,但保留相同的服务合同属性和操作FooAsync
样式ServiceContact.Name
与旧服务合同相同Async
版本而不是同步版本然后,您的客户端可以继续使用与旧服务器或新服务器通信的原始同步接口。