定时器崩溃程序的任务

时间:2011-04-13 13:09:20

标签: c#

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

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

5 个答案:

答案 0 :(得分: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;
        }
    }
}

答案 1 :(得分:0)

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

编写一个在解析文件时发送回调的事件。

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

答案 2 :(得分:0)

您是否尝试在OnTimeEvent内使用锁定声明?

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

答案 3 :(得分:0)

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

private static bool IsRunning = false;

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

答案 4 :(得分: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);
            }
        }
    }
}

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