2011-04-13 69 views
0

我有一個小程序,解析所有由另一個程序創建的日誌文件,並由它鎖定(所以,我無法編輯或刪除這些文件)。該程序運行得很好,和我做開始每10秒一個新的任務:任務定時器崩潰程序

System.Timers.Timer aTimer = new System.Timers.Timer(); 

public Form1() 
{ 
    InitializeComponent(); 

    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
    aTimer.Interval = 10000; 
    aTimer.Start(); 
} 

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    var t = Task<int>.Factory.StartNew(() => convert()); 
} 

當有太多日誌文件的唯一的問題出現了:如果一個新任務的前一個月底前開工該程序崩潰。 那麼,關於如何解決這種行爲的任何想法,或更好的解決問題的辦法?

+0

你如何創建你的aTimer Timer?你不重複使用,對嗎?發佈一些更多的代碼... – Marco 2011-04-13 13:12:11

+0

也許你用盡內存過多的日誌文件內存不足?沒有代碼很難說,但這似乎是一個合理的答案。 – skaz 2011-04-13 13:12:54

+0

發佈了一個示例代碼(它不是真正的代碼,它只是一個特別的修改:)) – kaharas 2011-04-13 13:18:51

回答

1

您可以使用lock()語句鎖定對象變量。另一方面,如果日誌文件的解析持續時間比定時器時間間隔長,則可能會遇到線程死鎖。

在您的OnTimedEvent()函數中,我會檢查一個布爾成員變量,如果您已經在執行解析,則跳過解析。例如:

public class MyTimerClass 
{ 
    private bool isParsing; 

    // Other methods here which initiate the log file parsing. 

    private void OnTimedEvent(object sender, ElapsedEventArgs e) 
    { 
     if (!isParsing) 
     { 
      isParsing = true; 
      ParseLogFiles(); 
      isParsing = false; 
     } 
    } 
} 
0

簡單的解決方案是等到上一個任務完成。

編寫一個事件,在文件完成解析時發送回調。

這是我能用所提供的代碼做的最好的。

0

您可以創建一個名爲IsRunning靜態布爾變量,並將其設置爲true,當你移動日誌,你開始移動日誌只是檢查是否IsRunning設置爲true之前。

private static bool IsRunning = false; 

public void MoveLogs() 
{ 
    if (!IsRunning) 
    { 
     IsRunning = true; 
     //Copy log files 
     IsRunning = false; 
    } 
} 
0

在當前接受的答案中,在多線程情況下仍然存在競爭條件的可能性。然而,在你的,因爲間隔的情況下不太可能的,另一種更合適的線程解決方案是使用Monitor.TryEnter

public class MyTimerClass 
{ 
    private object _syncObject = new object(); 

    // Other methods here which initiate the log file parsing. 

    private void OnTimedEvent(object sender, ElapsedEventArgs e) 
    { 
     if (Monitor.TryEnter(_syncObject)) 
     { 
      try 
      { 
       ParseLogFiles(); 
      } 
      finally 
      { 
       Monitor.Exit(_syncObject); 
      } 
     } 
    } 
} 

我相信這是更清潔,讓你在框架中使用正確的線程同步機制的習慣。