gpt4 book ai didi

c# - 队列的线程安全处理

转载 作者:太空宇宙 更新时间:2023-11-03 14:49:31 31 4
gpt4 key购买 nike

我将来自 UI 线程的任务放入队列中,以便它们可以在另一个线程中处理。如果无事可做,线程应该等待 AutoResetEvent - 显然所有这些都应该是线程安全的。

我像这样从 UI 线程将任务放入队列中:

lock (_syncObject)
{
_queue.Enqueue(new FakeTask());
}

_autoResetEvent.Set();

到目前为止,这是我的处理线程循环的样子:

while (true)
{
FakeTask task = null;
lock (_syncObject)
{
if (_queue.Count > 0)
{
task = _queue.Dequeue();
}
}

if (task != null)
{
task.Run();
Thread.Sleep(1000); //just here for testing purposes
}

if (_queue.Count == 0)
{
_autoResetEvent.WaitOne();
}
}

我担心我检查队列中是否有其他东西的最后一部分不是线程安全的,我想知道我如何做到这一点。谢谢!

最佳答案

简单情况下,尝试使用BlockingCollection 专门设计用于实现Producer / Consumer pattern :

private async Task Process() {
using (BlockingCollection<FakeTask> _queue = new BlockingCollection<FakeTask>()) {
Task producer = Task.Run(() => {
while (!completed) {
//TODO: put relevant code here
_queue.Add(new FakeTask());
}

_queue.CompleteAdding();
});

Task consumer = Task.Run(() => {
foreach (FakeTask task in _queue.GetConsumingEnumerable()) {
//TODO: process task - put relevant code here
}
});

await Task.WhenAll(producer, consumer).ConfigureAwait(false);
}
}

编辑:如果 producerUI thread 本身:

private async Task Process() {
using (BlockingCollection<FakeTask> _queue = new BlockingCollection<FakeTask>()) {
Task consumer = Task.Run(() => {
foreach (FakeTask task in _queue.GetConsumingEnumerable()) {
//TODO: process task - put relevant code here
}
});

// If we produce in UI we don't want any separate Task
while (!completed) {
//TODO: put relevant code here
_queue.Add(new FakeTask());
}

_queue.CompleteAdding();

await consumer.ConfigureAwait(false);
}
}

纠缠网格的情况下(例如,生产者#1、#2 为消费者#1、#2、#3 生成任务,而消费者又为...创建任务)尝试DataFlow

关于c# - 队列的线程安全处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52405703/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com