C#静态变量跨线程访问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13939976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Static Variable access across threads
提问by Rex Whitten
I am experiencing a bad behavior in my C# Multiple thread program. Some of my static members are loosing their values in other threads, while some statics of the same Declaring Type, do not loose their values.
我在 C# 多线程程序中遇到了不良行为。我的一些静态成员在其他线程中丢失了它们的值,而相同声明类型的一些静态成员不会丢失它们的值。
public class Context {
public Int32 ID { get; set; }
public String Name { get; set; }
public Context(Int32 NewID, String NewName){
this.ID = NewID;
this.Name = NewName;
}
}
public class Root {
public static Context MyContext;
public static Processor MyProcessor;
public Root(){
Root.MyContext = new Context(1,"Hal");
if(Root.MyContext.ID == null || Root.MyContext.ID != 1){
throw new Exception("Its bogus!") // Never gets thrown
}
if(Root.MyContext.Name == null || Root.MyContext.Name != "Hal"){
throw new Exception("It's VERY Bogus!"); // Never gets thrown
}
Root.MyProcessor = new MyProcessor();
Root.MyProcessor.Start();
}
}
public class Processor {
public Processor() {
}
public void Start(){
Thread T= new Thread (()=> {
if(Root.MyContext.Name == null || Root.MyContext.Name != "Hal"){
throw new Exception("Ive lost my value!"); // Never gets Thrown
}
if(Root.MyContext.ID == null){
throw new Exception("Ive lost my value!"); // Always gets thrown
}
});
}
}
IS this a thread mutation problem while using static members of certain types?
这是使用某些类型的静态成员时的线程突变问题吗?
采纳答案by TomTom
Use volatile
or alternatively access the variables using Interlocked.
使用volatile
或使用 Interlocked 访问变量。
The problem you run into is that the compiler (as well as the native compiler) is free to optimize access to the variables as he sees fit without them. So he may dump a variable into a register and just not reread it.
您遇到的问题是编译器(以及本机编译器)可以自由地优化对变量的访问,因为他认为没有它们就合适。所以他可能会将一个变量转储到一个寄存器中,而不是重新读取它。
In order to avoid it, you must make sure that the variable is actually REALLY read. Volatile does that. Interlocked does that as well (and allows increment / add etc. to happen atomically).
为了避免它,您必须确保该变量实际上已被真正读取。Volatile 就是这样做的。Interlocked 也是如此(并允许增量/添加等以原子方式发生)。
Which is better you have to decide. Both force a memory barrier onto the processor which does have a non trivial cost when done often. One pattern I use regularly is to have those objects read only mostly, so that I only replace the root object (one memory barrier). Dealing with memory barriers manually (possible, read manual for the keyword) is a pain to get right. It is, though, a lot more efficient - depending how much you do there etc. it may be needed.
你必须决定哪个更好。两者都将内存屏障强加到处理器上,这在经常执行时确实具有不小的成本。我经常使用的一种模式是大多数情况下只读取这些对象,以便我只替换根对象(一个内存屏障)。手动处理内存障碍(可能,阅读关键字的手册)很难做到。但是,它的效率要高得多 - 取决于您在那里做了多少等。可能需要它。
回答by VladL
Try using volatile
modifier on variables which are modified/accessed from multiple threads
尝试volatile
对从多个线程修改/访问的变量使用修饰符
回答by IT Seeker
Shared variables value in multi thread applications are non deterministic! you should use a lock on each of your shared resources to avoid collision in your logic:
多线程应用程序中的共享变量值是不确定的!您应该对每个共享资源使用锁以避免逻辑冲突:
static Readonly Object _lock=new Object();
lock(_lock)
{
//accessing your shared variable
}