繁体   English   中英

C#Singleton线程安全

[英]C# Singleton Thread Safety

我阅读了Jon Skeet关于如何实现C#单例的权威帖子 ,并遵循以下模式。 请注意,我没有空的ctor。 我的Ctor可能会做一些工作,比如创建和填充一个字符串数组(或者它可能会创建一些对象并将它们分配给私有变量等):

public class MyClass
    {                
        /// <summary>
        /// Get singleton instance of this class.
        /// </summary>
        public static readonly MyClass Instance = new MyClass();


        /// <summary>
        /// a collection of strings.
        /// </summary>
        private string[] strings;        

        private MyClass()
        {            
            this.strings = new string[]
            {
                "a",
                "b",
                "c",
                "d",
                "e" 
            };
        }

        public void MyMethod()
        {
           // tries to use this.strings.
           // can a null ref exception happen here when running multithreaded code?
        }
}

是线程安全吗? 我问,因为我有类似的代码在asp.net appserver上运行并在日志中得到null ref异常(不确定null ref是否与上述相关 - 我认为不是 - 并且日志中的调用堆栈没有帮助)。

老实说,我没有看到它不应该是线程安全的原因。 特别是考虑到Jon的第四个线程安全版本基本相同。

我看到的唯一问题是你没有静态构造函数。 (这可能会导致问题,请参阅此内容 )如果添加静态构造函数(即使它是空的),您将拥有Jon Skeet所谓的线程安全。

public class MyClass
{
    public static readonly MyClass Instance = new MyClass();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static MyClass() { }
}

根据提到的Jon Skeet文章,添加静态构造函数将导致此实现是线程安全的:

类型初始值设定项的懒惰只有在未使用名为beforefieldinit的特殊标志标记类型时才由.NET保证。 不幸的是,C#编译器(至少在.NET 1.1运行时中提供)标记所有没有静态构造函数的类型(即看起来像构造函数但被标记为静态的块)asfieldinit

(见http://csharpindepth.com/articles/general/singleton.aspx#cctor

正如你现在所拥有的那样,它不是线程安全的。 如果您执行此类操作,则会变为线程安全:

public class MyClass
{
    /// <summary>
    /// Get singleton instance of this class
    /// </summary>
    public static readonly MyClass Instance = new MyClass();

    static MyClass()
    {
        //causes the compiler to not mark this as beforefieldinit, giving this thread safety
        //for accessing the singleton.
    }

    //.. the rest of your stuff..
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM