c# - 拥有无限工作线程的正确方法?

标签 c# .net multithreading worker-thread

我有一个需要大量初始化的对象(在功能强大的机器上需要 1-2 秒)。虽然一旦初始化,完成一项典型的“工作”只需要大约 20 毫秒

为了防止它在每次应用程序想要使用它时都被重新初始化(在典型使用情况下可能是每秒 50 次或几分钟根本不初始化),我决定给它一个任务,并且让它在自己的线程上运行,检查队列中是否有任何工作。但是,我不完全确定如何创建一个在有或没有工作的情况下无限期运行的线程。

这是我目前的情况,欢迎大家批评

    private void DoWork()
    {
        while (true)
        {
            if (JobQue.Count > 0)
            {
                // do work on JobQue.Dequeue()
            }
            else
            {
                System.Threading.Thread.Sleep(50);
            }
        }
    }

经过思考:我在想我可能需要优雅地终止这个线程而不是让它永远运行,所以我想我会添加一个 Job 类型来告诉线程结束。任何关于如何结束这样的话题的想法也很感激。

最佳答案

无论如何,您需要锁定,这样您就可以等待Pulse:

while(true) {
    SomeType item;
    lock(queue) {
        while(queue.Count == 0) {
            Monitor.Wait(queue); // releases lock, waits for a Pulse,
                                 // and re-acquires the lock
        }
        item = queue.Dequeue(); // we have the lock, and there's data
    }
    // process item **outside** of the lock
}

加上像:

lock(queue) {
    queue.Enqueue(item);
    // if the queue was empty, the worker may be waiting - wake it up
    if(queue.Count == 1) { Monitor.PulseAll(queue); }
}

您可能还想看看 this question ,它限制了队列的大小(如果太满则阻塞)。

关于c# - 拥有无限工作线程的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1567040/

相关文章:

c# - 在任务中调用 CancellationTokenSource.Cancel() 不会将 Task.IsCanceled 设置为 true

c# - 使用 Roslyn 获取方法参数

c# - 我可以通过 Lucene 在 Orchard 中搜索/索引自定义数据源吗?

java - 下面的任务会捕获异常吗?

multithreading - 在 Scala Actor 中集成自主和 react 行为的最佳方式?

c# - 如果/如果否则/否则

C# ComboBox 项目不显示

c# - 无法将 lambda 表达式转换为类型 “string” 因为它不是委托(delegate)类型?

.net - 使用异步 .net 4.0 返回数据表

java - Java中的Mysql。如何实现高效的异步查询?