首页 > 解决方案 > .Net Core 3.1.6 ThreadLocal / ThreadStatic

问题描述

关于C# 的快速问题ThreadStatic,特别是 .Net Core 3.1.6..ThreadLocal

我宁愿不发布确切的示例,但它与此非常相似:

[ThreadStatic]
static readonly Object LocalObject = new Object();

ParrallelEnumerable然后我使用or从多个不同的线程访问所述对象Tasks.Parallel,我遇到了一个非常有趣的异常,不幸的是,它使运行时崩溃了......

我的代码的目的是每个Thread访问LocalObject都会有它自己的实例,如图所示

ThreadLocal.Net Core 3.1.6 周围/中是否有任何已知问题ThreadStatic,我可以在哪里阅读它们?

如果 3.1.6 没有任何指示更改或不同,那么 5.0 中是否存在与相同属性相关的更改?如果这些都没有,那么 .Net 核心是否从它们的完整框架实现中改变了这些构造的行为?

感谢您的时间!

标签: c#thread-local-storagethreadstatic

解决方案


根据您在链接中提供的文档,问题是当您访问变量时,该值为 null 因为:

需要注意的一件事是,如果我们初始化 ThreadStatic 变量,例如,如果我们编写以下代码

[ThreadStatic]
static int value = 10;

您需要注意,这仅在声明它的线程上初始化,所有使用 value 的线程都将获得一个使用其默认值初始化的变量,即 0。

所以,如果你试图对变量做一些事情,期望变量有一个Object实例,它会抛出一个异常,如果不处理就会导致应用程序失败。

编辑 - 2020 年 7 月 21 日

经过一番测试,我终于得出结论:该字段不可能是readonly由于初始化问题,即该字段只会在第一个线程,内联或static构造函数中初始化。任何后续thread只会获得一个null值。

我能得到的最接近如下:

public static void Main(string[] args)
{

    var tsk1 = Task.Run(() => {
       new Test().Display();
    });
    var tsk2 = Task.Run(() => {
       new Test().Display();
    });
    Task.WaitAll(new Task[] { tsk1, tsk2 });
}

class Test {
   [ThreadStatic]
   static Object _localObject;

   // Creates a new instance per thread.
   static Object LocalObject => _localObject ?? (_localObject = new Object());

   public void Display() {
      Console.WriteLine(LocalObject.GetHashCode());
   } 
}

// Sample output:
// C:\Test> dotnet run
// 4032828
// 6044116

推荐阅读