0

我有一个使用 .NET for Windows Azure 的 WebService。在那里我有一个单例类,它有一个在 while(true) 循环中做某事的方法。此方法使用单例中的实例变量。我在一个新线程中启动无限循环。当我更改实例变量的值(使用我的 web 服务)时,该值会更改。但是在无限循环的线程中,使用的是旧值。代码如下所示:

单例类

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 循环中使用旧值。那么如何更改创建线程中的值呢?

4

1 回答 1

4

问题是,默认情况下,编译器/运行时会进行很多涉及缓存值的优化。这在线程环境中成为一个问题,因为每个线程都有自己的缓存,因此即使他们认为它们是,它们也不会改变相同的变量。

有几个解决方案。

首先是使用volatile

private volatile int _interval;
public int Interval
{
    get
    {
        return _interval;
    }
    set
    {
        _interval = value;
    }
}

volatile是一种说法,“这可以从多个线程访问,确保在修改时缓存是同步的。

另一种是在访问变量时引入内存屏障。该lock语句隐含地执行此操作,但是由于该特定程序的全部要点似乎是无锁编程,因此这不是可取的;volatile 更适合您的特定需求。

于 2013-01-02T18:04:47.757 回答