2009-11-18 35 views
1

我的WCF服務使用netTcpBinding,並且有一個回調對象。WCF雙工通道在使用回調函數時關閉

我需要服務多個併發客戶端,和十個分量會議,所以服務上裝飾有

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple] 

爲了避免線程死鎖,回調類裝飾有

[CallbackBehavior(UseSynchronizationContext=false)] 

我用SynchronizationContext在UI線程中執行該方法。

問題是,有時頻道的關閉無意義(ICommunicationObject.Closing事件被觸發)。之後,我在任何後續服務電話中都會收到例外情況。

查看跟蹤文件,最後一條消息是回調函數,但是回調函數永遠不會被調用。沒有例外。

經過一些調試後,我發現只有在同步操作中間進行回調調用時纔會發生這種情況。具體的步驟是這樣的:

  1. 呼叫服務方法AIsOneWay=true
  2. 呼叫服務方法BIsOneWay=false
  3. A調用回調方法,但B仍在執行。

這應該不是問題,因爲回調有UseSynchronizationContext=false,所以回調調用可以在單獨的線程中處理。

我無法在更簡單的情況下重現問題。在一個簡單的項目中執行這些步驟將成功執行

任何想法可能發生什麼或如何識別問題?

+0

代碼片段可能會從客戶端和服務端受益。 – Perpetualcoder 2009-11-18 15:57:31

回答

9

我認爲可能發生的事情是客戶端錯誤的頻道,因爲它在收到回覆消息時收到回覆消息。在使用net.tcp的WCF中,回調和回覆使用相同的通道。

通常,您不應該在請求/回覆(IsOneWay = false)OperationContract方法體內調用回調方法。最安全的做法是在進行雙面打印時,在合同中不會有任何請求/回覆方法,但只要在返回之前不回調回調合同,就可以安全地使用它們。 (在例如從另一個工作線程返回之後,調用回調方法也可以)。

+0

+1很棒的信息。存儲將來。 – x0n 2012-01-06 18:40:31

0

感謝您的迴應! 我可以解決這個錯誤。

這是一個序列化問題,我在服務和回調行爲屬性中添加了IncludeExceptionsInFaults=true,然後我能夠看到錯誤。

問題是我正在發送一個DataTable與對象類型的列。

0

你應該在WCF包裝類的頂部添加此屬性:

[CallbackBehavior(UseSynchronizationContext=false)] 

從cauldwell.net:

的問題,事實證明,是ASP.NET使用(由默認)一個叫做SynchronizationContext的小東西。就我所知,我可以告訴 (我沒有徹底研究過,說實話)它的一個工作 它確保任何回調都可以在UI線程上運行,因此 可以避免需要調用Control.Invoke你在WinForms中做。在 我的情況下,那個額外的鎖給了一些適合的東西,它是 試圖清理東西在一個線程,沒有更多的, 因此NullReferenceException。

相關問題