5

System.Timers.Timer成为单例的成员有意义volatile static吗?

如果我在单例实例上下文中进行_fooTimer staticand or会有什么不同吗?volatile

如果我不做会有什么不同_instance static吗?

EDIT2:我更正了代码示例,现在使它变得更好单例,没有不必要的静态或易失性字段,并更改为 Interlock.Increment

public sealed class Foo
{
   private static readonly object _syncRoot;

   private int _counter; 

   private Timer _fooTimer;

   private static Foo _instance;

   private Foo()
   {
       _counter = 0;
       _syncRoot = new object();
       _fooTimer = new new Timer();
       _fooTimer.Intervall = 3600000;
       _fooTimer.Elapsed += new ElapsedEventHandler(LogFoo);
   }

   public static Foo Instance
   {
        get
        {
            lock(_syncRoot)
            {
                 if (_instance == null)
                 {
                      _instance = new Foo();
                 }
            }
            return _instance;
        }
    }

    private void LogFoo()
    {
         // write a logfile with _counter - then restart timer and set _counter to 0
    }

    public void Increment()
    {
         Interlocked.Increment(_counter);
    }
}

public class UseTheFoo
{         
     // Foo.Instance.Increment()         

     ...
}
4

2 回答 2

9

通常,单例类中唯一的静态变量是对单个实例的引用。然后,您将对类型的剩余状态使用实例变量。如果您将其设为静态,那么您甚至不需要创建该类的单个实例来使用计时器 - 但我希望您无论如何都希望这样做。

我也会对使用感到紧张volatile......它几乎肯定并不完全意味着你认为它的意思。我可能会改用它Interlocked来实现对变量的原子更新。

(请注意,根据我关于该主题的文章,有很多更好的方法来实现它。)

编辑:现在代码已更改为显示更多成员,这有点令人困惑。有一个静态方法可以使用_counter(一个实例变量)——大概是通过单例实例。基本上,该类似乎还没有决定是要成为一堆静态方法还是单例实例。我建议您决定并以一种或另一种方式访问​​所有内容,但不要混合使用。

于 2013-01-29T15:58:28.283 回答
1

通过将整个类设为静态,您可以将创建实例期间的任何线程同步问题推送到 CLR:

public static class Foo
{
  private static Timer _fooTimer;

  static Foo()
  {
     _fooTimer = new Timer();
  }
}
于 2013-01-29T16:00:26.070 回答