2011-04-13 53 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); 
      } 
     } 
    } 
} 

我相信这是更清洁,让你在框架中使用正确的线程同步机制的习惯。