c# - 如何确保线程任务正在运行

标签 c# threadpool

并不是特定于语言的,但我在 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 = falsewhile 循环就不可能完成 - 如果不是这种情况,则会出现竞争条件循环在该方法的另一个实例开始时完成。同样,当调用该方法时,它总是会进入循环并在另一个实例有机会执行之前设置_isRunning = true

关于c# - 如何确保线程任务正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12496750/

相关文章:

java - Java ThreadPoolExecutor [提交的内容超过MaxPoolSize]

c# - 寻找 .NET 的 MetaWebLog 客户端库。一个存在吗?

c# - VSTO 字 2016 : Squiggly underline without affecting undo

c# - LINQ、Lambda、C#、扩展方法

c# - 从控制台应用程序异步调用 Azure 移动服务

c# - 进度条不工作

java - 使用 shutdownNow() 方法时获取我使用 ScheduledThreadPoolExecutor 计划的 Runnable 对象

c++ - 如何等待此线程池中的所有任务完成?

c# - 为什么对级联 ManualResetEvent 的多次等待会使执行时间增加三倍?

java - 使用 ExecutorService 时不会调用 Thread.interrupt