2012-03-14 24 views
0

我用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 

爲什麼會出現這種執行在三分鐘的時間間隔兩次:在14.03.2012 09:20:59.985和14.03.2012 09:21:00.010?

我在哪裏必須解決這個問題?

CurrentTime我必須補充30秒這樣

DateTime now = DateTime.Now.AddSeconds(30)還是什麼?

+0

什麼是你的currentTime屬性在做什麼?這看起來很奇怪!你只是想創建一個每隔三分鐘就會觸發一次的計時器嗎?如果是這樣,你的代碼太複雜了。 – ColinE 2012-03-14 06:08:51

+0

我使用CurrentTime屬性來糾正計時器精確到三分鐘的時間間隔,並且讓這段時間寫到數據庫 – amaranth 2012-03-14 06:16:14

回答

2

這裏有幾個問題。最大的一個我看到的是你的CurrentTime屬性:

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; 

考慮當now.Minute59,59/3 = 19,因爲這是一個int會發生什麼。表達式的其餘部分59/3 * 3 - 59的結果爲-2。你已經有效地將計時器倒回兩分鐘。 但是,因爲您在創建val時清零了秒數,所以您確實已將計時器設置回3分鐘。 59並不是一個獨特的例子,但我從你的數據點集中拉出來。使用您的CurrentTime的代碼會增加3分鐘。所以你幾乎要告訴代碼立即觸發。你都看到了兩次上調的原因是因爲這條線在ShowText的:

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

當你的委託處理計時器,該事件被立即再次因爲now.Minute仍然59,導致整體CurrentTime計算爲3升起小於DateTime.Now的分鐘數。

如果你想要做的是有一個任務運行每三分鐘,再下面是你需要:

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

,發現很好 - 我知道當前有什麼可疑的東西! – ColinE 2012-03-14 06:22:52

+0

但按下按鈕時間不總是等於三分鐘的時間間隔,所以我使用CurrentTime – amaranth 2012-03-14 06:38:13

+0

@amaranth,您需要多長時間接近3分鐘的時間間隔?根據您所需的精度,這可能不總是可能的。或者你是否試圖在小分界線上舉辦活動? – Tung 2012-03-14 06:42:55