gpt4 book ai didi

c# - 初始化 ThreadStatic 字段仍然导致 NullReferenceException

转载 作者:IT王子 更新时间:2023-10-29 04:01:12 28 4
gpt4 key购买 nike

我自己写了一个多线程随机生成器

public static class MyRandGen
{
private static Random GlobalRandom = new Random();
[ThreadStatic]
private static Random ThreadRandom = new Random(SeedInitializer());
private static int SeedInitializer()
{
lock (GlobalRandom) return GlobalRandom.Next();
}

public static int Next()
{
return ThreadRandom.Next();
}
}

但是,它在触发 Next() 时抛出一个 NullReferenceException,我不明白。是否以某种方式禁止初始化 ThreadStatic 字段?

我知道我可以每次都检查该字段是否已初始化,但这不是我正在寻找的解决方案。

最佳答案

初始化 ThreadStatic 字段有点棘手。特别是有这个警告:

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.

MSDN Docs .这意味着在初始化类时运行的线程获得您在字段声明中定义的初始值,但所有其他线程的值为 null。我认为这就是为什么您的代码表现出问题中描述的不良行为的原因。

更完整的解释在 this blog 中.

(来自博客的片段)

[ThreadStatic]
private static string Foo = "the foo string";

The ThreadStatic is initialized in the static constructor - which only executes once. So only the very first thread is assigned "the foo string" when the static constructor executes. When accessed in all subsequent threads, Foo is left at the uninitalized null value.

The best way to work around this is to use a property to access the Foo prop.

[ThreadStatic]
private static string _foo;

public static string Foo {
get {
if (_foo == null) {
_foo = "the foo string";
}
return _foo;
}
}

请注意,不需要在静态属性中加锁,因为每个线程都作用于仅供该线程使用的 _foo。不能与其他线程争用。这包含在这个问题中:ThreadStatic and Synchronization

关于c# - 初始化 ThreadStatic 字段仍然导致 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18086235/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com