Eu tenho uma classe que contém um arquivo BlockingCollection<Task>
usado para enfileirar uma série de tarefas para serem executadas em ordem (FIFO).
A fila em si é iniciada em uma tarefa separada de longa execução.
public class TaskQueue
{
private readonly BlockingCollection<Task> _queue = new BlockingCollection<Task>();
public TaskQueue()
{
Task.Factory.StartNew(() =>
{
ProcessQueue();
}, TaskCreationOptions.LongRunning);
}
private async Task ProcessQueue()
{
foreach (var task in _queue.GetConsumingEnumerable())
await task;
}
...
}
Quando o aplicativo é iniciado, crio muitas instâncias, TaskQueue
pois preciso de filas diferentes para diferentes componentes do aplicativo.
O problema que estou vendo é que, embora ProcessQueue()
seja iniciado em uma tarefa LongRunning .NET Long Running Task
, após a primeira espera da tarefa, ela retorna, ou .NET ThreadPool Worker
seja, não é mais uma tarefa de longa execução.
Isso resulta em todas as instâncias TaskQueue.ProcessQueue
terminando .NET ThreadPool Workers
(após a primeira espera), o que faz com que o aplicativo fique muito lento para iniciar novas tarefas, pois atingiu o número máximo de execuções simultâneas .NET ThreadPool Workers
(acredito que isso esteja definido como o número de núcleos que a máquina possui, no meu caso 8), após os quais ela só criará novos .NET ThreadPool Workers
a cada segundo ou mais.
Então minhas perguntas são:
- Existe uma maneira de retornar a uma tarefa de longa duração?
- Ou devo apenas substituir
Task.Factory.StartNew
por um novo Thread? que acredito que resolverá o problema, mas não tenho certeza se existe uma maneira melhor.