У меня есть очередь, в которую помещаются ожидающие обработки запросы преобразования Фурье (сравнительно трудоемкие операции) - в некоторых случаях мы можем получать тысячи запросов на преобразование в секунду, поэтому это должно быть быстро.
Я обновляю старую версию код для использования .net 4, а также перенос на TPL. Мне интересно, как выглядит наиболее эффективный (самый быстрый) способ обработки этой очереди. Я хочу использовать все доступные ядра.
В настоящее время я экспериментирую с BlockingCollection. Я создаю класс обработчика очереди, который порождает 4 задачи, которые блокируются в BlockingCollection и ждут входящей работы. Затем они обрабатывают это ожидающее преобразование. Код:
public class IncomingPacketQueue : IDisposable
{
BlockingCollection<IncomingPacket> _packetQ = new BlockingCollection<IncomingPacket>();
public IncomingPacketQueue(int workerCount)
{
for (int i = 0; i < workerCount; i++)
{
Task.Factory.StartNew(Consume);
}
}
public void EnqueueSweep(IncomingPacket incoming)
{
_packetQ.Add(incoming);
}
private void Consume()
{
foreach (var sweep in _packetQ.GetConsumingEnumerable())
{
//do stuff
var worker = new IfftWorker();
Trace.WriteLine(" Thread {0} picking up a pending ifft".With(Thread.CurrentThread.ManagedThreadId));
worker.DoIfft(sweep);
}
}
public int QueueCount
{
get
{
return _packetQ.Count;
}
}
#region IDisposable Members
public void Dispose()
{
_packetQ.CompleteAdding();
}
#endregion
}
Похоже, это хорошее решение? Кажется, что все ядра исчерпаны, хотя в настоящее время я не уверен, сколько воркеров мне нужно создать в своем конструкторе.