5

System.Timers.Timerシングルトンのメンバーにするのは理にかなっていvolatile staticますか?

シングルトン インスタンス コンテキストで_fooTimer staticand またはを作成しても違いはありますか?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 に答える