2011-06-02 74 views
0

http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.messagebuffer(v=vs.85).aspx在說時有些含糊其詞「此類型的任何公共靜態(Visual Basic中的Shared)成員都是線程安全的,但不保證所有實例成員都是線程安全的。WCF MessageBuffer.CreateMessage是否線程安全?

作爲一般規則,似乎實例成員沒有線程安全保證。

但是,我猜一些實例成員方法是可重入的,線程安全的,而其他的方法不是。

MessageBuffer.CreateMessage是一個實例方法。 有沒有人確認這種特定的方法是否可重入(或者調用者是否需要實現對方法調用的鎖定)?

回答

1

我不認爲要明確指定,實例方法總是非線程安全的。你可以通過反射器來看這個方法來確認。
此外,爲什麼你關心這種方法的線程安全?你的使用場景是什麼?

+0

我們的服務維護多個MessageBuffers。這些緩衝區用於頻繁創建消息。 我想避免每個CreateMessage調用的同步構造開銷(除非,當然,CreateMessage調用不可重入) – ServerCode 2011-06-02 20:59:39

+0

您將獲得圍繞創建消息添加同步構造的方法。 CreateMessage不會改變原始對象的狀態,所以如果創建消息被調用一次或多次,它如何起作用。 – Chandermani 2011-06-03 04:22:38

+0

如果該方法不可重入(如您所想的那樣),則需要添加同步結構以確保該方法不會同時由兩個不同線程執行 – ServerCode 2011-06-06 01:59:30

1

MessageBuffer.CreateMessage是抽象的,所以詢問它是否線程安全沒有意義。 WCF中的MessageBuffer的子類都是內部的,所以它們可能會被更改。正如Chandermani所說,你應該假設它不是線程安全的。

更新:它不是線程安全的。創建的消息可能依賴於其他組件,例如消息體的序列化。如果這些組件不是線程安全的,那麼CreateMessage調用也不能被認爲是線程安全的。

在下面的例子中,對象的序列化版本是時間依賴的(它也可能有一些額外的依賴關係),所以CreateMessage調用的順序影響結果。

public class StackOverflow_6209650_751090 
{ 
    [DataContract] 
    public class MyDC 
    { 
     [DataMember] 
     public DateTime SerializedTime 
     { 
      get { return DateTime.Now; } 
      set { } 
     } 
    } 
    public static void Test() 
    { 
     Message message = Message.CreateMessage(MessageVersion.None, "foo", new MyDC()); 
     var buffer = message.CreateBufferedCopy(int.MaxValue); 
     Console.WriteLine(buffer.CreateMessage()); 
     Console.WriteLine(); 
     Console.WriteLine(buffer.CreateMessage()); 
    } 
} 
+0

CreateBuffer方法不關心我。 我在引用由Message.CreateBufferedCopy創建的MessageBuffer對象(特別是如果此對象的CreateMessage方法是可重入的)。 – ServerCode 2011-06-02 21:06:12

+0

Message.CreateBufferedCopy內部調用一個虛方法OnCreateBufferedCopy,這取決於所創建的消息的類型。另外,我將用一個示例顯示它肯定不是**線程安全的編輯我的答案。 – carlosfigueira 2011-06-02 21:20:01

+0

感謝Carlos的例子,我已經提高了您的評論。但是,DateTime.Now方法(在您的示例中使用)是線程安全的。如你所說,返回值是時間依賴的。但是,這並不意味着DateTime.Now不是線程安全的或不可重入的。相反,DateTime.Now是一個線程安全的方法。 無論如何,我創建的特定消息不是基於時間的。我正在緩存MessageBuffer,因爲數據(靜態xml)在緩存期間不會更改。我的猜測是CreateMessage是可重入的,但需要驗證這一點。 – ServerCode 2011-06-03 04:07:23