并不是特定于语言的,但我在 C# 中有这个:
public static void StartJob() {
ThreadPool.QueueUserWorkItem(s => {
if (Monitor.TryEnter(_lock)) {
ProcessRows();
Monitor.Exit(_lock);
}
}
);
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);
}
使用此结构,如果不设置 _isRunning = false
,while
循环就不可能完成 - 如果不是这种情况,则会出现竞争条件循环在该方法的另一个实例开始时完成。同样,当调用该方法时,它总是会进入循环并在另一个实例有机会执行之前设置_isRunning = true
。
关于c# - 如何确保线程任务正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12496750/