如何确保运行线程任务

时间:2012-09-19 14:20:28

标签: c# threadpool

不是特定语言,但我在C#中有这个:

public static void StartJob() {
    ThreadPool.QueueUserWorkItem(s => {
        if (Monitor.TryEnter(_lock)) {
            ProcessRows();
            Monitor.Exit(_lock);
        }
    }
);

ProcessRows()处理并删除数据库中的行,直到删除所有行。在程序启动时,只要在程序的其他位置向数据库添加行,就会调用StartJob,以确保处理所有行而不阻塞程序。现在,如果在StartJob即将释放锁的同时添加一行,则不会处理该行。

如何确保处理所有行?除非添加行,否则我不希望ProcessRows()运行。

1 个答案:

答案 0 :(得分:2)

不要锁定方法;使用一个标记来锁定方法,该标记表示您是否正在运行。

一个实现可能看起来像下面的代码 - 在这种情况下,我已将所有逻辑移动到ProcessRows并使该方法立即返回,如果它已经在运行。

public static bool _isRunning = false;

public static void StartJob() 
{ 
    ThreadPool.QueueUserWorkItem(s => { ProcessRows(); })
} 

public static void ProcessRows()
{
    Monitor.Enter(_lock);
    if (_isRunning) 
    {
        Monitor.Exit(_lock);
        return;
    }

    _isRunning = true;

    while (rowsToProcess)
    {
        Monitor.Exit(_lock);;

        // ... do your stuff

        Monitor.Enter(_lock);
    }

    _isRunning = false;
    Monitor.Exit(_lock);
}

使用这种结构,while循环不可能在没有设置_isRunning = false的情况下完成 - 如果不是这种情况,如果循环完成就像另一个实例一样,就会出现竞争条件方法开始了。同样,当调用该方法时,它将始终进入循环并在另一个实例有机会执行之前设置_isRunning = true