gpt4 book ai didi

队列上的 C# 锁和多线程

转载 作者:行者123 更新时间:2023-11-30 19:06:45 25 4
gpt4 key购买 nike

我正在编写一个多线程应用程序,我担心 2 个线程访问一个队列

线程 1 将项目放入队列中进行处理线程 2 从队列中移除项目以进行处理

由于线程 1 提取的数据的性质,它每分钟运行一次。线程 2 一直在运行,它从队列中删除一个项目并休眠 100 毫秒。我必须这样做以确保在它使项目出列时我不会淹没它调用的服务。

我假设两个线程在从队列中添加或删除项目时都应该在队列上放置一个锁。有没有进一步的考虑?例如,线程 1 有一个锁,线程 2 试图访问它。线程 2 是否只知道在锁被移除后等待并恢复?

使用 ConcurrentQueue 和 TryDequeue 是否更可取,如果它失败,则继续其 100 毫秒休眠?

提前致谢

最佳答案

如果使用 BlockingCollection<T> 会更容易就像我在 NuGet 的 VS 控制台调度程序中为我的 PostKey/WaitKey 实现所做的那样。消费线程调用 Take(...)这将阻塞直到另一个线程调用 Add(...) .无需轮询。此外,您可能希望将取消 token 传递给 Take方法,以便另一个线程可以在当前正在等待 Add 时停止使用者线程。那永远不会到来。以下是相关方法:

private readonly BlockingCollection<VsKeyInfo> _keyBuffer = 
new BlockingCollection<VsKeyInfo>();
private CancellationTokenSource _cancelWaitKeySource;

// place a key into buffer
public void PostKey(VsKeyInfo key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
_keyBuffer.Add(key);
}

// signal thread waiting on a key to exit Take
public void CancelWaitKey()
{
if (_isExecutingReadKey && !_cancelWaitKeySource.IsCancellationRequested)
{
_cancelWaitKeySource.Cancel();
}
}

// wait for a key to be placed on buffer
public VsKeyInfo WaitKey()
{
try
{
// raise the StartWaitingKey event on main thread
RaiseEventSafe(StartWaitingKey);

// set/reset the cancellation token
_cancelWaitKeySource = new CancellationTokenSource();
_isExecutingReadKey = true;

// blocking call
VsKeyInfo key = _keyBuffer.Take(_cancelWaitKeySource.Token);

return key;
}
catch (OperationCanceledException)
{
return null;
}
finally
{
_isExecutingReadKey = false;
}
}

参见 http://nuget.codeplex.com/SourceControl/changeset/view/45e353aca7f4#src%2fVsConsole%2fConsole%2fConsole%2fConsoleDispatcher.cs了解更多详情。

关于队列上的 C# 锁和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9405784/

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