2012-03-14 25 views
0

私は正確に3分間隔取得するSystem.Threading.Timerを使用します。System.Threading.Timer間隔

private System.Threading.Timer ReadTimer; 
     private System.Threading.TimerCallback ReadTimerCallback; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     #region Working with RichTextBox and system event log for logging 
     public enum LogStyle 
     { 
      InformationStyle = 0, 
      WarningStyle = 1, 
      ErrorStyle = 3 
     } 
     private delegate void LogTextDelegate(LogStyle logStyle, string message); 
     private int NewLinesCount(string Message) 
     { 
      string[] strings = { Environment.NewLine }; 
      return Message.Split(strings, StringSplitOptions.RemoveEmptyEntries).Count(); 
     } 
     private void AddText(LogStyle logStyle, string message) 
     { 
      LogBox.Select(0, 0); 
      string TextToAppend = DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + " " + message + Environment.NewLine; 
      LogBox.AppendText(TextToAppend); 
      LogBox.Select(LogBox.TextLength - TextToAppend.Length + NewLinesCount(TextToAppend), TextToAppend.Length); 
      switch (logStyle) 
      { 
       case LogStyle.InformationStyle: 
        { 
         EventLog.WriteEntry(Process.GetCurrentProcess().ProcessName, TextToAppend, EventLogEntryType.Information); 
         LogBox.SelectionColor = Color.Green; 
         LogBox.Select(LogBox.TextLength, LogBox.TextLength); 
         break; 
        } 
       case LogStyle.WarningStyle: 
        { 
         EventLog.WriteEntry(Process.GetCurrentProcess().ProcessName, TextToAppend, EventLogEntryType.Warning); 
         LogBox.SelectionColor = Color.DarkOrange; 
         LogBox.Select(LogBox.TextLength, LogBox.TextLength); 
         break; 
        } 
       case LogStyle.ErrorStyle: 
        { 
         EventLog.WriteEntry(Process.GetCurrentProcess().ProcessName, TextToAppend, EventLogEntryType.Error); 
         LogBox.SelectionColor = Color.Red; 
         LogBox.Select(LogBox.TextLength, LogBox.TextLength); 
         break; 
        } 
      } 
     } 
     public void LogText(LogStyle logStyle, string Message) 
     { 
      if (LogBox.InvokeRequired) 
      { 
       LogBox.Invoke(new LogTextDelegate(this.AddText), new object[] { logStyle, Message }); 
      } 
      else 
      { 
       AddText(logStyle, Message); 
      } 
     } 
     #endregion 

     private void button1_Click(object sender, EventArgs e) 
     { 
      LogText(LogStyle.WarningStyle, "Current thread ID = " + System.Threading.Thread.CurrentThread.ManagedThreadId); 
      LogText(LogStyle.WarningStyle, "Threads count = " + System.Diagnostics.Process.GetCurrentProcess().Threads.Count); 
      AutoResetEvent ReadautoEvent = new AutoResetEvent(false); 
      ReadTimerCallback = new TimerCallback(this.ShowText); 
      ReadTimer = new System.Threading.Timer(ReadTimerCallback, ReadautoEvent, (long)(CurrentTime.AddMinutes(3) - DateTime.Now).TotalMilliseconds, 180000); 

     } 

     public void ShowText(object Object) 
     { 
      ReadTimer.Change((long)(CurrentTime.AddMinutes(3) - DateTime.Now).TotalMilliseconds, 180000); 
      LogText(LogStyle.WarningStyle, "Now is " + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff")); 
      LogText(LogStyle.WarningStyle, "Now is " + "Current thread ID = " + System.Threading.Thread.CurrentThread.ManagedThreadId); 
      LogText(LogStyle.WarningStyle, "Threads count = " + System.Diagnostics.Process.GetCurrentProcess().Threads.Count); 
     } 

     private DateTime CurrentTime 
     { 
      get 
      { 

       DateTime now = DateTime.Now; 
       DateTime val; 
       val = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0) 
        .AddMinutes(((now.Minute)/3) * 3 - now.Minute); 
       return val; 
      } 
     } 

をしかし、時には、私は以下を参照してください。

14.03.2012 09:20:33.264 Current thread ID = 10 
14.03.2012 09:20:33.361 Threads count = 13 
14.03.2012 09:20:59.985 Now is 14.03.2012 09:20:59.977 
14.03.2012 09:20:59.991 Now is Current thread ID = 12 
14.03.2012 09:20:59.997 Threads count = 15 
14.03.2012 09:21:00.010 Now is 14.03.2012 09:21:00.009 
14.03.2012 09:21:00.019 Now is Current thread ID = 12 
14.03.2012 09:21:00.025 Threads count = 17 
14.03.2012 09:24:00.252 Now is 14.03.2012 09:24:00.252 
14.03.2012 09:24:00.260 Now is Current thread ID = 8 
14.03.2012 09:24:00.268 Threads count = 17 
14.03.2012 09:27:00.331 Now is 14.03.2012 09:27:00.330 
14.03.2012 09:27:00.337 Now is Current thread ID = 6 
14.03.2012 09:27:00.343 Threads count = 14 
14.03.2012 09:30:00.021 Now is 14.03.2012 09:30:00.021 
14.03.2012 09:30:00.027 Now is Current thread ID = 8 
14.03.2012 09:30:00.033 Threads count = 13 
14.03.2012 09:32:59.962 Now is 14.03.2012 09:32:59.961 
14.03.2012 09:32:59.968 Now is Current thread ID = 6 
14.03.2012 09:32:59.974 Threads count = 13 
14.03.2012 09:33:00.013 Now is 14.03.2012 09:33:00.013 
14.03.2012 09:33:00.020 Now is Current thread ID = 6 
14.03.2012 09:33:00.026 Threads count = 14 
14.03.2012 09:35:59.891 Now is 14.03.2012 09:35:59.891 
14.03.2012 09:35:59.898 Now is Current thread ID = 8 
14.03.2012 09:35:59.904 Threads count = 13 
14.03.2012 09:36:00.001 Now is 14.03.2012 09:35:59.999 
14.03.2012 09:36:00.008 Now is 14.03.2012 09:36:00.004 
14.03.2012 09:36:00.015 Now is Current thread ID = 8 
14.03.2012 09:36:00.021 Now is Current thread ID = 6 
14.03.2012 09:36:00.030 Threads count = 14 
14.03.2012 09:36:00.035 Threads count = 14 

なぜこれが実行さありません3分間隔で2回:14.03.2012 09:20:59.985および14.03.2012 09:21:00.010?

私はこの問題を解決しなければならない

CurrentTime

私は30秒な

DateTime now = DateTime.Now.AddSeconds(30)または何を追加する必要がありますか?

+0

をしているのですか?これは奇妙に見えます! 3分ごとに起動するタイマーを作成しようとしていますか?もしそうなら、あなたのコードははるかに複雑です。 – ColinE

+0

CurrentTimeプロパティを使用して、正確な3分間隔のタイマーを修正し、この時間をDBに書き込むようにします。 – amaranth

答えて

2

いくつかの問題がここにあります。

DateTime now = DateTime.Now; 
DateTime val; 
val = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0) 
       .AddMinutes(((now.Minute)/3) * 3 - now.Minute); 
return val; 

が、これはint型であるため、now.Minute59、3分の59 = 19であるときに何が起こるかを考えてみましょう:私が見る最大のものは、あなたのCurrentTimeプロパティです。式59/3 * 3 - 59の残りの部分は-2になります。タイマーを2分後に効果的に巻き戻しました。 の場合、valを作成した秒数をゼロにしたので、実際には3分後にタイマーを設定しています。 59はユニークなケースではありませんが、私はデータポイントのセットからそれを引き出しています。 CurrentTimeを使用するコードでは3分が加算されます。だからあなたはすぐにコードを発射するように指示しています。あなたはそれが二度上げ見ている理由は、ShowTextであるため、この行は次のとおりです。

`ReadTimer.Change((long)(CurrentTime.AddMinutes(3) - DateTime.Now).TotalMilliseconds, 180000);` 

デリゲートは、タイマーを処理するときnow.Minuteはまだ59あるので、イベントはあなたの全体的なCurrentTime計算があることを引き起こして、すぐに再び上昇さ3分未満DateTime.Now。

あなたがしたいすべてのタスクは3分ごとに実行した場合は、次はあなたが必要とするすべてである:あなたのCurrentTimeをプロパティには、何を

ReadTimer = new System.Threading.Timer(ReadTimerCallback, ReadautoEvent, 0, 180000); 
+0

よく知りました。 – ColinE

+0

しかし、ボタンの時間が3分間隔に等しくないので、CurrentTime – amaranth

+0

@amaranthで作業するので、3分間隔にどれくらい近づける必要がありますか?必要とされる正確さに応じて、これは必ずしも可能ではないかもしれません。または、イベントを分単位で発生させようとしていますか? – Tung