我是審查WCF服務的代碼。 在每封郵件的標題中,我們會注入該服務稍後將用於建立到數據庫的連接字符串的數據。 這是因爲服務將被許多不同的站點使用,每個站點都有自己的數據庫,服務必須查詢。 我們使用wcf的可擴展性。我們有一個自定義MessageInspector的是,在接收到請求之後,從所述郵件頭中提取數據,創建上下文(實現IExtension)並將其添加到OperationContext.Current.Extensions。 在發送回覆之前,自定義上下文將從Extencions集合中刪除。WCF Operation.Context不是線程安全的?
這是一個相當普遍的圖案,如這裏討論:
Where to store data for current WCF call? Is ThreadStatic safe?
和這裏:
這所有隻要服務接收的請求工作正常,流程它發送回覆並接收下一個請求。 但是如果服務收到請求並且在能夠回覆請求之前獲得第二個請求呢?我構建了一個小型控制檯應用程序來測試它。我從2個不同的線程發送2條消息,我讓wcf服務等待2秒,以確保第二個請求在第一個請求完成之前進入,這是我得到的:
站點ID:test1450;會話:uuid:2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 2:線程ID:6
站點ID:test1450;會話:uuid:2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 3:線程ID:22
它看起來像wcf創建2個會話在2個不同的線程上執行,但網站ID是相同的。它不應該。由此判斷,它看起來像OperationContext.Current.Extensions是線程之間共享的集合。 現在我傾向於認爲我的測試是錯誤的,我錯過了一些東西。
有沒有人嘗試過類似的東西,並發現OperationContext.Current不是線程安全的?
如果是這樣的話,那我還是不明白,爲什麼我會得到相同的網站ID。如果每個線程都應該得到不同的數據,那麼我認爲它應該得到包含在正在處理的消息中的站點ID。它看起來像每個線程(不同的會話ID)當前操作上下文是不同的,但仍然擴展集合似乎包含相同的自定義上下文的實例。 – Hoppers13
如果可能有所幫助:我嘗試以不同的方式配置服務器:InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Single – Hoppers13
這是它的原始配置方式; InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple。但問題是相同的 – Hoppers13