2017-09-29 43 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版本的服務合同的不同步一個

那麼您的客戶可以繼續使用原來的同步接口聊到舊的或新的服務器。