我有一个使用.NET for Windows Azure的WebService。在那里,我有一个单例类,它有一个方法在while(true)循环中执行某些操作。此方法使用单例中的实例变量。我在新线程中启动无限循环。 当我更改实例变量的值(使用我的webservice)时,值会更改。但是在infinty循环的线程中使用旧值。 代码如下所示:
Singleton Class
public class Singleton
{
static Singleton _instance;
public static Singleton Instance
{
get { return _instance ?? (_instance = new Singleton()); }
}
private Singleton() {
this.Intervall = -20;
}
public int Intervall { get; set; }
public void run()
{
Thread thread = new Thread(privateRun);
thread.Start();
}
private void privateRun()
{
while (true)
{
// do something with Intervall Value
Trace.WriteLine(this.Intervall);
}
}
}
在WebRole onstart();
中启动run方法public override bool OnStart()
{
// start the singleton method
Singleton singleton= Singleton.Instance;
singleton.run();
return base.OnStart();
}
并从WebService更改值
public string setIntervall(int Intervall)
{
Singleton.Instance.Intervall = Intervall;
return "New Intervall: " + Singleton.Instance.Intervall;
}
WebService真的返回新的Intervall。但是在while循环中使用旧值。那么如何更改创建的线程中的值?
答案 0 :(得分:4)
问题在于,默认情况下,编译器/运行时会进行大量涉及缓存值的优化。这在线程环境中成为一个问题,因为每个线程都有自己的缓存,因此即使他们认为它们也不会改变相同的varialbe。
有一些解决方案。
第一种是使用volatile
:
private volatile int _interval;
public int Interval
{
get
{
return _interval;
}
set
{
_interval = value;
}
}
volatile
是一种说法,“这可以从多个线程访问,确保在修改缓存时同步缓存。
另一种方法是在访问变量时引入内存屏障。 lock
语句隐含地执行此操作,但由于此特定程序的重点似乎是无锁编程,因此这不是优选的;不稳定适合您的特殊需求。