C# 如何确保线程化任务已运行

C# 如何确保线程化任务已运行,c#,threadpool,C#,Threadpool,不是特定于语言,但我有C语言: ProcessRows()处理并删除数据库中的行,直到删除所有行。在程序启动时,只要将一行添加到程序中其他位置的数据库中,就会调用StartJob,以确保在不阻塞程序的情况下处理所有行。现在,如果在StartJob即将释放锁的同时添加一行,则不会处理该行 如何确保处理所有行?除非添加行,否则我不希望运行ProcessRows()。不要锁定该方法;使用表示是否正在运行的标志锁定方法 一个实现可能与下面的代码类似——在本例中,我将所有逻辑移到了ProcessRows中

不是特定于语言,但我有C语言:


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


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

不要锁定该方法;使用表示是否正在运行的标志锁定方法

一个实现可能与下面的代码类似——在本例中,我将所有逻辑移到了
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);
}

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

您需要向数据库中添加行的东西来向您的程序发出信号,表明它可以开始处理。您可以使用一些全局互斥。“现在,如果在StartJob即将释放锁的同时添加一行,则不会对其进行处理。”-您确定吗?这发生在你身上了吗?@DanielHilgarth:这不太可能,但是那里有一个理论上的竞争条件,因为
ProcessRows
在释放锁之前完成;第二个线程可能会使
.TryEnter
失败,即使
ProcessRows
没有运行。@DanPuzey:你是对的。我没有正确阅读,并认为其他线程将阻塞,直到锁被释放(如Monitor.Enter)。
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);
}