2011-06-02 148 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