2009-10-29 171 views
3

我有一個相當直接的WCF服務,爲一堆智能客戶端執行單向文件同步。我注意到,在通話過程中出現網絡或服務中斷時,客戶端將停止與服務器通信,直到整個應用程序重新啓動。WCF客戶端掛起服務中斷

該服務使用BasicHttpBinding運行,並使用IIS6(.svc頁面),使用transferMode="Streamed"messageEncoding="Mtom"。該服務被配置爲使用默認的InstanceContextMode(我認爲它是Per Call?)和ConcurrencyMode = Single。它使用默認的限制行爲,但我處於沒有其他人正在擊中的獨立測試環境中。

客戶端是Windows服務。我使用這個ServiceProxyHelper確保連接是Close()'d或Abort()'d當Dispose()'d,雖然沒有會話,所以我不認爲這甚至很重要。發生錯誤時,客戶端對象被丟棄,然後超出範圍。在檢測到異常之後,服務會等待一段時間,然後創建一個新的客戶端對象並再次嘗試。所以它應該從失敗中恢復,但由於某種原因,後續對該服務的所有調用都會失敗。

我可以通過啓動客戶端來可靠地重現這一點,允許它傳輸幾個文件,然後重新設置服務器。首先,客戶端通常顯示「服務太忙」錯誤(映射到在應用程序重新啓動期間獲得的IIS 503錯誤)。之後,所有後續的服務呼叫超時。據我所知,這些呼叫甚至沒有被客戶嘗試。我啓用了跟蹤,看到的是:超時錯誤,後面跟着一個「無法通過HTTP發送請求消息」的警告,接着是另一個超時錯誤。

瘋狂的事情是,當我配置客戶端使用Fiddler(端口8888)作爲app.config中的代理時,一切都按需要工作。所以不知何故Fiddler作爲代理正在關閉或終結某種WCF本身不存在的連接。

想法?

編輯2009-10-30 8:54 PM:將服務屬性更改爲:InstanceContextMode = Single和ConcurrencyMode = Multiple。沒有不同。

回答

2

那真是痛苦。它花了我一直,但最後我把注意力放在了運行代理與沒有運行之間的差異上,並開始撥動<system.net>設置。事實證明,將此配置位添加到客戶端可以修復問題:

<system.net> 
    <settings> 
     <servicePointManager expect100Continue="false" /> 
    </settings> 
    </system.net> 

有人可以解釋發生了什麼嗎?爲什麼這個設置會導致WCF客戶端在服務中斷時無法挽回地掛起?

+0

在'WebRequest'中有關於100繼續功能的已知錯誤。 http://regis.decamps.info/blog/2010/12/c-bug-in-webrequest/ – rds 2011-01-03 18:15:51

0

您確定這不是客戶端問題。如果您的Windows服務正在從主服務器的單獨線程上進行WCF調用,並且您在子線程上發生了未處理的異常......調用線程可能會或可能不會坐在那裏並永遠等待因爲它正在等待爲該線程返回。

這可以解釋爲什麼服務內部有一個Exception,然後看起來服務不再打電話給服務......它被掛起。

在.NET 2.0 Windows Services中使用計時器產生進程時,曾經是一個巨大的問題。

+0

我認爲這是一個客戶端問題,但我不認爲它是線程,雖然你說的正確的是,這些客戶端是在不同的線程上產生的,而不是主要的。我正在使用BackgroundWorker而不是線程,並且在線程出錯時掛鉤到RunWorkerCompleted事件中以重新啓動。我看到這個邏輯被執行,我看到工作人員再次啓動並試圖與服務進行通信。這些後續的呼叫失敗了。 – roufamatic 2009-10-29 23:09:44