如何只读静态字段为空?

所以这是我的一个课程的摘录:

[ThreadStatic] readonly static private AccountManager _instance = new AccountManager(); private AccountManager() { } static public AccountManager Instance { get { return _instance; } } 

如您所见,它是每个线程的单例 – 即该实例标有ThreadStatic属性。 该实例也被实例化为静态构造的一部分。

既然如此,当我尝试使用Instance属性时,我的ASP.NET MVC应用程序中是否有可能出现NullReferenceException?

引用MSDN ThreadStaticAttribute :

不要为标记有ThreadStaticAttribute的字段指定初始值,因为这样的初始化只在类构造函数执行时发生一次,因此只影响一个线程。 如果未指定初始值,则可以依赖于初始化为默认值的字段(如果它是值类型),或者如果它是引用类型则依赖于空引用(在Visual Basic中为Nothing)。

这是ThreadStatic属性的一个令人困惑的部分。 即使它为每个线程创建一个值,初始化代码也只在其中一个线程上运行。 访问此值的所有其他线程将获得该类型的默认值,而不是初始化代码的结果。

而不是值初始化,将其包装在为您进行初始化的属性中。

 [ThreadStatic] readonly static private AccountManager _instance; private AccountManager() { } static public AccountManager Instance { get { if ( _instance == null ) _instance = new AccountManager(); return _instance; } } 

因为每个线程的值_instance是唯一的,所以在属性中不需要锁定,并且它可以像任何其他延迟初始化值一样对待。

你在这里击中了经典的[ThreadStatic] “101”。

静态初始化程序只会触发一次, 即使它被标记为[ThreadStatic] ,因此其他线程(除了第一个)将看到未初始化。

我相信正在发生的事情是静态字段只被初始化一次所以当另一个线程尝试读取字段时它将为null(因为它是默认值),因为_instance不能再次初始化。 它只是一个想法,但我可以完全离开,但这就是我认为正在发生的事情。

标记为ThreadStaticAttribute的静态字段不在线程之间共享。 每个执行线程都有一个单独的字段实例,并独立设置和获取该字段的值。 如果在另一个线程上访问该字段,则它将包含不同的值。