带有计时器的任务使程序崩溃

本文关键字:程序 崩溃 任务 计时器 | 更新日期: 2023-09-27 17:49:52

我有一个小程序,它解析由另一个程序创建的所有日志文件,并被它锁定(因此,我无法编辑或删除这些文件)。程序运行得很好,我每隔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());
}

唯一的问题出现在日志文件太多的时候:如果一个新任务在前一个任务结束之前启动,程序就会崩溃。那么,对于如何解决这种行为,或者更好的解决方案,有什么想法吗?

带有计时器的任务使程序崩溃

可以使用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;
        }
    }
}

简单的解决方案是等待前一个任务完成。

写一个事件,当文件解析完成时发送一个回调。

这是我所能做的最好的代码。

您是否尝试在OnTimeEvent中使用锁语句?

http://msdn.microsoft.com/en-us/library/c5kehkcz (v = VS.100) . aspx

你可以创建一个名为IsRunning的静态布尔变量,并在你移动日志时将其设置为true,在你开始移动日志之前只需检查IsRunning是否设置为true。

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

在当前公认的答案中,在多线程情况下仍然存在竞争条件的可能性。但是由于间隔的原因,在您的情况下不太可能,另一个更适合线程的解决方案是使用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);
            }
        }
    }
}

我相信这样更简洁,并且可以让您养成在框架中使用适当的线程同步机制的习惯。