簡體   English   中英

委派同步WCF調用以啟動異步過程

[英]Delegating a synchronous WCF call to start an asynchronous process

我需要修改WCF方法以異步運行。 在我的情況下, [OperationContract(IsOneWay=true)]不是有效的選項,因為客戶期望返回值。 我無法控制客戶端對現有WCF方法調用的使用,也無法更改簽名以返回void. 我也無法修改客戶端以強制執行異步WCF調用。 客戶端仍然必須期望調用其同步WCF調用並獲得其硬編碼響應。

在服務內,存在用於管理監視和異常的行為。 我正在考慮的選項是讓WCF服務自動注冊或自我發現其端點,向該服務添加單向WCF方法,並使同步方法在WCF上調用單向方法。 我認為這是確保所有現有行為仍然適用的最安全的方法。 這些行為不會收集或依賴最終客戶端的任何信息。 盡管從現有的同步調用中啟動其他線程或異步調用在技術上似乎是可行的,但我不喜歡這樣做,因為我認為這可能會破壞與當前WCF OperationContext綁定的狀態信息。

看來,我探索過的與此相關的所有選項都需要某種折衷,並且將同步呼叫轉移到單向呼叫的選項是最安全的。 有沒有更好的方法可以解決此問題,還是可以強制WCF方法將與OneWay調用相同的立即返回給客戶端,但包括返回值?

有兩種方法可以解決此問題。 您已經確定了其中一個(“鏈式WCF調用”)。 另一個確實涉及TPL技術和技巧。

鏈接的WCF呼叫。

使用這種方法時,請記住WCF交互最昂貴的部分是有效載荷/參數的(反序列化)。 在延遲方面,您的客戶端將支付兩次價格,因為您已將端點“鏈接”在一起。 “單向”調用配置仍然要求客戶端“等待”,直到所有參數正確反序列化為止,並且調用“看起來不錯”。 這是因為單向調用仍具有向調用者發出SOAP異常的能力,指示非法參數或崩潰的WCF行為等。只有“端點工作”(您編程的部分)的延遲才會被“保存”,使用這種技術。

使用這種方法,您還必須考慮您的單向例程必須配置為具有與原始端點大多數或所有相同的行為。 對於異常處理方面尤其如此。 你說:

在OperationContext中存儲了一個有狀態對象,該對象維護有關流程的信息。 例如,如果存在異常,它將把所有相關過程信息保存為一個包。

聽起來您想從原始入口點剝離所有或大多數行為,而是讓它們裝飾您的內部單向例程。

TPL Finesse

Note: this next approach likely solves only half your problem...
because it does not address the WCF exception-handing scenario 
you called out.

通常,因為它是[ThreadStatic],所以您要擔心OperationContext在線程和TPL例程之間不流動是正確的。 但是,根據MSDN,OperationContext.Current屬性是公共的。 使用閉包,您應該能夠將WCF請求線程中的OperationContext手動分配給新Task的新OperationContext.Current。

在這種情況下,您可以允許主WCF請求線程返回...而新的Task可以使用相同的OperationContext引用運行。 如果在新Task上拋出異常,則肯定不會通過自定義WCF行為對其進行處理,因為主要WCF請求線程可能早就已經退出並返回了,因此它已經“遍歷”了所有(異常處理)行為層。

簡而言之,這給您帶來的唯一好處是,如果WCF行為已將交易ID標記到OperationContext中,則該交易ID將手動流到新Task上……從而允許下游例程將其提取。

如果您要遵循這種方法,則:

  • 嘗試確保仍有一個回調在等待后台Task ...它的目的是捕獲任何異常,如有必要,請記錄並吞下。 您不希望WCF應用程序中的獨立Task具有未處理的異常。 請記住,在這種情況下,您不會從WCF行為獲得幫助。
  • 確保任務具有相當有限的延遲...例如400到800ms。 您不希望任務運行5分鍾。 大概您的WCF應用程序是由IIS托管的,並且IIS可以在沒有警告的情況下重新加載或卸載WCF AppDomain ...因為它不知道您已經創建了仍在工作的新Task。 只要延遲受到限制,我懷疑IIS會“過早”關閉WCF應用程序時會遇到問題。

最后,如果您的情況比這更復雜,請注意自定義TaskScheduler實例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM