У меня есть очередь, на которую размещаются ожидающие запросы преобразования Фурье (относительно длительные операции) - в некоторых случаях мы могли бы получать тысячи запросов на преобразование в секунду, поэтому его нужно быстро.
Я обновляю старый код, чтобы использовать .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
}
Это похоже на хорошее решение? Похоже, что все ядра - это максимум, хотя я в настоящее время не знаю, сколько рабочих я должен создать в своем конструкторе.