C# 什么';在生产者/消费者中处理无限任务的最有效方法是什么?

C# 什么';在生产者/消费者中处理无限任务的最有效方法是什么?,c#,concurrency,producer-consumer,C#,Concurrency,Producer Consumer,我在一个云队列(Azure)中存储了千兆字节的数据(存储在消息中,每条消息大约500KB),数据不断出现 我需要对每条消息进行一些处理。我决定创建两个后台工作程序,一个用于将数据放入内存,另一个用于处理该数据: GetMessage(CloudQueue cloudQueue, LocalQueue localQueue) { lock (localQueue) { localQueue.Enqueue(cloudQueue.Dequeue()); } }

我在一个云队列(Azure)中存储了千兆字节的数据(存储在消息中,每条消息大约500KB),数据不断出现

我需要对每条消息进行一些处理。我决定创建两个后台工作程序,一个用于将数据放入内存,另一个用于处理该数据:

GetMessage(CloudQueue cloudQueue, LocalQueue localQueue)
{
    lock (localQueue)
    {
        localQueue.Enqueue(cloudQueue.Dequeue());
    }
}

ProcessMessage(LocalQueue localQueue)
{
    lock (localQueue)
    {
        Process(localQueue.Dequeue());
    }
}

问题是数据总是源源不断,所以我将花费大量时间同步本地队列。是否存在此类问题的已知模式?

在处理过程中,您不需要持有锁

Item i;
lock (localQueue)
{
    i = localQueue.Dequeue();
}
Process(i);

因此,应该没有什么争议。如有必要,通过批处理插入来减少生产者获取排队锁的频率:而不是队列保留单个项目,让它保留批处理。有效地减少了锁的数量,减少的系数是平均批量大小。您可以有一个简单的批处理模型,例如,每10次或按时间或时间与阈值的某种组合。

在处理过程中,您不需要持有锁

Item i;
lock (localQueue)
{
    i = localQueue.Dequeue();
}
Process(i);

因此,应该没有什么争议。如有必要,通过批处理插入来减少生产者获取排队锁的频率:而不是队列保留单个项目,让它保留批处理。有效地减少了锁的数量,减少的系数是平均批量大小。您可以有一个简单的批处理模型,例如,每10次或按时间或时间与阈值的某种组合。

在处理过程中,您不需要持有锁

Item i;
lock (localQueue)
{
    i = localQueue.Dequeue();
}
Process(i);

因此,应该没有什么争议。如有必要,通过批处理插入来减少生产者获取排队锁的频率:而不是队列保留单个项目,让它保留批处理。有效地减少了锁的数量,减少的系数是平均批量大小。您可以有一个简单的批处理模型,例如,每10次或按时间或时间与阈值的某种组合。

在处理过程中,您不需要持有锁

Item i;
lock (localQueue)
{
    i = localQueue.Dequeue();
}
Process(i);

因此,应该没有什么争议。如有必要,通过批处理插入来减少生产者获取排队锁的频率:而不是队列保留单个项目,让它保留批处理。有效地减少了锁的数量,减少的系数是平均批量大小。您可以有一个简单的批处理模型,例如,每10次或按时间或时间与阈值的某种组合。

您真的相信这是一个问题吗?与实际处理消息所花费的时间相比,您认为锁定花费了多少精力?(很可能有简单的无锁方法,但我还没有看到任何证据表明锁定实际上是有意义的…@JonSkeet我运行了VS analyzer,发现它在锁定上花费了大约20%(可能是因为处理线程正在饥饿)你所说的“锁定”到底是什么意思?在锁内,还是实际执行锁?正如djna所指出的(我没有愚蠢地发现),您当前正在锁中处理队列消息,这是一个非常糟糕的主意。。。但这并不意味着你在实际的同步上花费了很多时间。你真的相信这是个问题吗?与实际处理消息所花费的时间相比,您认为锁定花费了多少精力?(很可能有简单的无锁方法,但我还没有看到任何证据表明锁定实际上是有意义的…@JonSkeet我运行了VS analyzer,发现它在锁定上花费了大约20%(可能是因为处理线程正在饥饿)你所说的“锁定”到底是什么意思?在锁内,还是实际执行锁?正如djna所指出的(我没有愚蠢地发现),您当前正在锁中处理队列消息,这是一个非常糟糕的主意。。。但这并不意味着你在实际的同步上花费了很多时间。你真的相信这是个问题吗?与实际处理消息所花费的时间相比,您认为锁定花费了多少精力?(很可能有简单的无锁方法,但我还没有看到任何证据表明锁定实际上是有意义的…@JonSkeet我运行了VS analyzer,发现它在锁定上花费了大约20%(可能是因为处理线程正在饥饿)你所说的“锁定”到底是什么意思?在锁内,还是实际执行锁?正如djna所指出的(我没有愚蠢地发现),您当前正在锁中处理队列消息,这是一个非常糟糕的主意。。。但这并不意味着你在实际的同步上花费了很多时间。你真的相信这是个问题吗?与实际处理消息所花费的时间相比,您认为锁定花费了多少精力?(很可能有简单的无锁方法,但我还没有看到任何证据表明锁定实际上是有意义的…@JonSkeet我运行了VS analyzer,发现它在锁定上花费了大约20%(可能是因为处理线程正在饥饿)你所说的“锁定”到底是什么意思?在锁内,还是实际执行锁?正如djna所指出的(我没有愚蠢地发现),您当前正在锁中处理队列消息,这是一个非常糟糕的主意。。。但这并不意味着你要花很多时间在实际的同步上。