2013-10-10 59 views
16

我是審查WCF服務的代碼。 在每封郵件的標題中,我們會注入該服務稍後將用於建立到數據庫的連接字符串的數據。 這是因爲服務將被許多不同的站點使用,每個站點都有自己的數據庫,服務必須查詢。 我們使用wcf的可擴展性。我們有一個自定義MessageInspector的是,在接收到請求之後,從所述郵件頭中提取數據,創建上下文(實現IExtension)並將其添加到OperationContext.Current.Extensions。 在發送回覆之前,自定義上下文將從Extencions集合中刪除。WCF Operation.Context不是線程安全的?

這是一個相當普遍的圖案,如這裏討論:

Where to store data for current WCF call? Is ThreadStatic safe?

和這裏:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/319cac66-66e8-4dfe-9a82-dfd289c9df1f/wcf-doesnt-have-session-storage-so-where-should-one-store-call-specific-data?forum=wcf

這所有隻要服務接收的請求工作正常,流程它發送回覆並接收下一個請求。 但是如果服務收到請求並且在能夠回覆請求之前獲得第二個請求呢?我構建了一個小型控制檯應用程序來測試它。我從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不是線程安全的?

回答

11

OperationContext.Current等其他類似的性質,例如具有HttpContext.Current螺紋仿射(或線程靜態)值。所以它們在多線程可以讀取它們的意義上是線程安全的,但不同的線程會得到不同的實例。它們可以被認爲是特定線程和實例之間的字典。

所以在這種情況下,他們是線程安全的。

請求由一個線程池這樣的併發請求都會有不同的線程ID服務。 (最多到一個地步,線程池已滿,則請求將被暫時擱置)

+0

如果是這樣的話,那我還是不明白,爲什麼我會得到相同的網站ID。如果每個線程都應該得到不同的數據,那麼我認爲它應該得到包含在正在處理的消息中的站點ID。它看起來像每個線程(不同的會話ID)當前操作上下文是不同的,但仍然擴展集合似乎包含相同的自定義上下文的實例。 – Hoppers13

+0

如果可能有所幫助:我嘗試以不同的方式配置服務器:InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Single – Hoppers13

+0

這是它的原始配置方式; InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple。但問題是相同的 – Hoppers13

相關問題