所以这是我的一个课程的摘录:
[ThreadStatic]
readonly static private AccountManager _instance = new AccountManager();
private AccountManager()
{
}
static public AccountManager Instance
{
get { return _instance; }
}
如您所见,它是每个线程的单例 - 即该实例标有ThreadStatic属性。该实例也被实例化为静态构造的一部分。
既然如此,当我尝试使用Instance属性时,我的ASP.NET MVC应用程序中是否有可能出现NullReferenceException?
答案 0 :(得分:38)
不要指定初始值 标有的字段 ThreadStaticAttribute,因为这样 初始化只发生一次,何时 类构造函数执行,和 因此只影响一个线程。如果 你没有指定初始值, 你可以依靠现场 如果它初始化为其默认值 是值类型,还是null 引用(在Visual Basic中没有任何内容)if 它是一种参考类型。
答案 1 :(得分:12)
这是ThreadStatic
属性的一个令人困惑的部分。即使它为每个线程创建一个值,初始化代码也只在其中一个线程上运行。访问此值的所有其他线程将获得该类型的默认值,而不是初始化代码的结果。
而不是值初始化,将其包装在为您进行初始化的属性中。
[ThreadStatic]
readonly static private AccountManager _instance;
private AccountManager()
{
}
static public AccountManager Instance
{
get
{
if ( _instance == null ) _instance = new AccountManager();
return _instance;
}
}
因为每个线程的值_instance
是唯一的,所以在属性中不需要锁定,并且可以将其视为任何其他延迟初始化值。
答案 2 :(得分:8)
你在这里击中了经典的[ThreadStatic]
“101”。
静态初始化程序只会触发一次,即使它被标记为[ThreadStatic]
,所以其他线程(除了第一个)都会看到这个未初始化。
答案 3 :(得分:1)
我相信正在发生的事情是静态字段只被初始化一次,所以当另一个线程尝试读取字段时它将为null(因为它是默认值),因为_instance不能再次初始化。它只是一个想法,但我可以完全离开,但这就是我认为正在发生的事情。
答案 4 :(得分:0)
线程之间不共享标有ThreadStaticAttribute的静态字段。每个执行线程都有一个单独的字段实例,并独立设置和获取该字段的值。如果在另一个线程上访问该字段,它将包含不同的值。