簡體   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