C# 如何实施BlockingCollection来解决此生产者/消费者问题?
我目前有一个应用程序正在从套接字接收数据包,处理它们并将它们添加到ConcurrentQueue。然后我有一个单独的线程来处理这些项目 我遇到的问题是生产者/消费者问题,消费者在没有任何项目的情况下也试图获取项目,从而导致大量cpu使用 ProcessPackets在其自己的线程上运行:C# 如何实施BlockingCollection来解决此生产者/消费者问题?,c#,multithreading,C#,Multithreading,我目前有一个应用程序正在从套接字接收数据包,处理它们并将它们添加到ConcurrentQueue。然后我有一个单独的线程来处理这些项目 我遇到的问题是生产者/消费者问题,消费者在没有任何项目的情况下也试图获取项目,从而导致大量cpu使用 ProcessPackets在其自己的线程上运行: private ConcurrentQueue<PrimaryPacket> Waiting = new ConcurrentQueue<PrimaryPacket>();
private ConcurrentQueue<PrimaryPacket> Waiting = new ConcurrentQueue<PrimaryPacket>();
private void ProcessPackets()
{
PrimaryPacket e;
while (true)
{
if (Waiting.TryDequeue(out e))
{
Packets.TryAdd(((ulong)e.IPAddress << 32 | e.RequestID), e);
}
}
}
public void AddPacket(PrimaryPacket e)
{
Waiting.Enqueue(e);
}
private ConcurrentQueue Waiting=new ConcurrentQueue();
私有void ProcessPackets()
{
初生的;
while(true)
{
if(等待.TryDequeue(out e))
{
Packets.TryAdd(((ulong)e.IPAddress您不必实现,只需使用它即可。正如文档所述,它只是IProducerConsumerCollection
的包装器,例如ConcurrentQueue
(这是默认的)
private BlockingCollection正在等待=
新BlockingCollection();
私有void ProcessPackets()
{
while(true)
{
PrimaryPacket e=等待.Take();
Packets.TryAdd((ulong)e、 IPAddress duplicated请参见:我尝试过此方法,但它无法跟上每秒向队列中添加30000个项目的速度。我很难相信这一点。AutoResetEvent不是最快的方法,但30000确实不是那么多。您可以尝试使用ManualResetEventSlim,它在初始阶段使用spincount,但实际上应该如此除非ProcessPackets中有需要很长时间的代码(但这超出了本问题的范围),否则不必这样做我刚刚用BlockingCollection
进行了测试,每秒的吞吐量约为2000000。发布的代码肯定跟不上,它会消耗100%的内核。你必须给线程调度程序一个机会,让它在准备处理数据时唤醒你的线程。就像BlockingCollection一样。循环会让你丢失线程谢谢。我在睡觉前就想出了这个方法。真不敢相信这么简单。
private BlockingCollection<PrimaryPacket> Waiting =
new BlockingCollection<PrimaryPacket>();
private void ProcessPackets()
{
while (true)
{
PrimaryPacket e = Waiting.Take();
Packets.TryAdd(((ulong)e.IPAddress << 32 | e.RequestID), e);
}
}
public void AddPacket(PrimaryPacket e)
{
Waiting.Add(e);
}