0

500ms間隔でx回実行することになっているタイマーがあります。現在、私のコードは次のようになっています。

 var i = 0;
 var times = 10;
 timer = new System.Threading.Timer(_ =>
 {
    if (timer == null || i >= times)
        return;

    Console.WriteLine("Run " + i);

    if (i < times - 1)
        i++;
    else
    {
        timer.Dispose();
        timer = null;
    }
 }, null, 500, 500);

タイマー変数で作成および参照されるのが1つだけであることを確認した場合、これはタイマーをキャンセルするための信頼できる方法ですか?

間隔の量は実行時に可変です。

4

2 に答える 2

2

タイマーの廃棄にはかなり安全に見えます。i変数とtimes変数をプライベートにし、メソッドの一部ではありません。これにより、より高速なコードが作成されます。また、タイマーデリゲートが異なるスレッドで同時に実行されている可能性がわずかにあります。http://msdn.microsoft.com/en-us/library/system.threading.timer.aspxを参照してください。したがって、Interlockedを使用する可能性があります。 。インクリメント方法。

多分このようなもの:

class Foo
{
  volatile int runCount;
  int maxRunCount;
  Timer timer;

  void RunFor(int max)
  {
    maxRunCount = max;
    timer = new System.Threading.Timer(_ =>
    {
      if (timer == null) return;
      Console.WriteLine("Run " + runCount);

      if (Interlocked.Increment(ref runCount) == maxRunCount)
      {
          timer.Dispose();
          timer = null;
      }
    }, null, 500, 500);
  }
}

[編集]

コードを確認すると、競合状態を防ぐために、タイマーの破棄の周りにロックをかけることがあります。

    if (...)
    {
       lock(this)
       {
          if (timer != null) timer.Dispose();
          timer = null;
       }
     }
于 2012-12-11T13:42:47.703 に答える
1

System.Timers.Timer代わりにクラスを使用する必要があります...それはとメソッド
の両方をサポートします。Stop()Start()

簡単な例:

System.Timers.Timer timer = new System.Timers.Timer();
var i = 0;
var times = 10;


public SetupTimer()
{
    timer.Interval = 500;
    timer.Elapsed += OnTimerElapsed;
    timer.Start();
}

private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    // Logic

    if (i > times)
    {
       timer.Stop();
    }
}
于 2012-12-11T13:42:32.300 に答える