只读静态字段怎么可能为空?

发布于 2024-08-18 00:24:30 字数 426 浏览 10 评论 0原文

下面是我的一个类的摘录:

    [ThreadStatic]
    readonly static private AccountManager _instance = new AccountManager();

    private AccountManager()
    {
    }

    static public AccountManager Instance
    {
        get { return _instance; }
    }

如您所见,它是每个线程的单例 - 即该实例用 ThreadStatic 属性标记。该实例也作为静态构造的一部分进行实例化。

既然如此,当我尝试使用 Instance 属性时,我怎么可能在 ASP.NET MVC 应用程序中遇到 NullReferenceException?

So here's an excerpt from one of my classes:

    [ThreadStatic]
    readonly static private AccountManager _instance = new AccountManager();

    private AccountManager()
    {
    }

    static public AccountManager Instance
    {
        get { return _instance; }
    }

As you can see, it's a singleton-per-thread - i.e. the instance is marked with the ThreadStatic attribute. The instance is also instantiated as part of static construction.

So that being the case, how is it possible that I'm getting a NullReferenceException in my ASP.NET MVC application when I try to use the Instance property?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

可遇━不可求 2024-08-25 00:24:30

引用 MSDN ThreadStaticAttribute

不要指定初始值
标记为的字段
ThreadStaticAttribute,因为这样
初始化仅发生一次,当
类构造函数执行,并且
因此只影响一个线程。如果
您没有指定初始值,
您可以信赖该领域
初始化为其默认值,如果
是值类型,或者为 null
参考(Visual Basic 中无任何内容)如果
它是一个引用类型。

Quoting MSDN ThreadStaticAttribute:

Do not specify initial values for
fields marked with
ThreadStaticAttribute, because such
initialization occurs only once, when
the class constructor executes, and
therefore affects only one thread. If
you do not specify an initial value,
you can rely on the field being
initialized to its default value if it
is a value type, or to a null
reference (Nothing in Visual Basic) if
it is a reference type.

少女七分熟 2024-08-25 00:24:30

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

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

[ThreadStatic]
readonly static private AccountManager _instance;

private AccountManager()
{
}

static public AccountManager Instance
{
  get 
  { 
    if ( _instance == null ) _instance = new AccountManager();
    return _instance; 
  }
}

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

This is a confusing part of the ThreadStatic attribute. Even though it creates a value per thread, the initalization code is only run on one of the threads. All of the other threads which access this value will get the default for that type instead of the result of the initialization code.

Instead of value initialization, wrap it in a property that does the initialization for you.

[ThreadStatic]
readonly static private AccountManager _instance;

private AccountManager()
{
}

static public AccountManager Instance
{
  get 
  { 
    if ( _instance == null ) _instance = new AccountManager();
    return _instance; 
  }
}

Because the value _instance is unique per thread, no locking is necessary in the property and it can be treated like any other lazily initialized value.

晌融 2024-08-25 00:24:30

您在这里遇到了经典的[ThreadStatic]“101”。

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

You've hit a classic [ThreadStatic] "101" here.

The static initializer will only fire once, even though it is marked as [ThreadStatic], so other threads (apart from the first) will see this uninitialised.

趁微风不噪 2024-08-25 00:24:30

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

I believe what is happening is that the static field is only being initialized once so when another thread tries to read the field it will be null (since its the default value) because _instance can't be initialized again. Its just a thought but and I could be totally way off but that's what I think is happening.

寻找一个思念的角度 2024-08-25 00:24:30

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

A static field marked with ThreadStaticAttribute is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文