C# 如何实施BlockingCollection来解决此生产者/消费者问题?

C# 如何实施BlockingCollection来解决此生产者/消费者问题?,c#,multithreading,C#,Multithreading,我目前有一个应用程序正在从套接字接收数据包,处理它们并将它们添加到ConcurrentQueue。然后我有一个单独的线程来处理这些项目 我遇到的问题是生产者/消费者问题,消费者在没有任何项目的情况下也试图获取项目,从而导致大量cpu使用 ProcessPackets在其自己的线程上运行: private ConcurrentQueue<PrimaryPacket> Waiting = new ConcurrentQueue<PrimaryPacket>();

我目前有一个应用程序正在从套接字接收数据包,处理它们并将它们添加到ConcurrentQueue。然后我有一个单独的线程来处理这些项目

我遇到的问题是生产者/消费者问题,消费者在没有任何项目的情况下也试图获取项目,从而导致大量cpu使用

ProcessPackets在其自己的线程上运行:

    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);
}