根据我对 .NET 的了解,不可能跨不同线程访问变量。如果该说法有误,请纠正我,这只是我在某处读到的内容。
该声明完全错误,因此请将此视为您的更正。
你可能在某处读到过局部变量不能跨不同线程访问。该声明是also错误的,但通常是这样说的。正确的说法是局部变量不是
- 在异步方法中
- 在迭代器块中(即带有
yield return
or yield break
)
- 匿名函数的封闭外部变量
不能被多个线程访问。即使这样的说法也有点狡猾。有一些方法可以用指针来做到这一点unsafe
代码块,但尝试这样做是一个非常糟糕的主意。
我还注意到您的问题询问局部变量,但随后给出了一个示例field。根据定义,字段是not局部变量。局部变量是根据定义局部于方法体。 (或构造函数主体、索引器主体等)确保您对此很清楚。局部变量的定义特征不是它位于“堆栈上”或类似的东西;而是它位于“堆栈上”或诸如此类的东西。本地的“本地”部分是它的名称在方法体之外没有意义.
一般情况下:变量是存储位置指的是memory。一个线程是一个过程中的控制点,并且进程中的所有线程共享相同的内存;这就是让他们threads并不是流程。所以一般来说,所有变量都可以被多个线程在任何时间、以任何顺序访问,除非建立某种机制来防止这种情况发生.
让我再说一遍,只是为了确保您头脑中绝对清楚:考虑单线程程序的正确方法是所有变量都是stable除非有什么事情让他们改变。考虑多线程程序的正确方法是所有变量都是不断变异 in 没有特别的顺序除非有什么东西让他们保持静止或秩序井然。这就是多线程的共享内存模型如此困难的根本原因,以及为什么你应该避免它。
在您的特定示例中,两个线程都可以访问this
,因此两个线程都可以看到变量this.variable
。您没有实现任何机制来防止这种情况,因此两个线程都可以按任何顺序写入和读取该变量,实际上受到的约束很少。您可以实施一些机制来抑制这种行为:
- 将变量标记为
ThreadStatic
。这样做会导致在每个线程上创建一个新变量。
- 将变量标记为
volatile
。这样做会对如何观察读取和写入的顺序施加某些限制,并且还会对编译器或 CPU 进行的优化施加某些限制,从而可能导致意外结果。
- Put a
lock
围绕变量的每个用法的声明。
- 首先不要共享变量。
除非你有一个deep由于了解多线程和处理器优化,我建议不要选择除后者之外的任何选项。
现在,假设您确实希望确保在另一个线程上对该变量的访问失败。您可以让构造函数捕获创建线程的线程 ID 并将其存储起来。然后,您可以通过属性 getter/setter 访问该变量,其中 getter 和 setter 检查当前线程 ID,如果与原始线程 ID 不同,则抛出异常。
本质上这是你自己的单线程单元线程模型。 “单线程单元”对象是只能在创建它的线程上合法访问的对象。 (你买了一台电视,把它放在你的公寓里,只有你公寓里的人才能看你的电视。)单线程公寓与多线程公寓与自由线程的细节变得相当复杂;有关更多背景信息,请参阅此问题。
您能解释一下 STA 和 MTA 吗? https://stackoverflow.com/questions/127188/could-you-explain-sta-and-mta
例如,这就是为什么您绝不能从工作线程访问在 UI 线程上创建的 UI 元素; UI 元素是 STA 对象。