Если вы хотите сохранить простоту, поставьте в очередь действие вместо задачи. Поскольку мы ставим в очередь асинхронные вызовы, тип очереди - Func<Task>
. Используйте две очереди для разных приоритетов.
ConcurrentQueue<Func<Task>> _highPriorityQueue;
ConcurrentQueue<Func<Task>> _lowPriorityQueue;
Затем создайте рабочего профи c, чтобы проверить обе очереди в порядке приоритетов.
async Task WorkerProc(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
Func<Task> action;
if (_highPriorityQueue.TryDequeue(out action))
{
await action();
continue;
}
if (_lowPriorityQueue.TryDequeue(out action))
{
await action();
continue;
}
await Task.Yield();
}
}
Затем запустите несколько потоков для работы очередь:
var source = new CancellationTokenSource();
var threads = Enumerable.Range(0, numberOfThreads).Select( i =>
Task.Run( () => WorkerProc(source.GetToken()) )
).ToList();
И для добавления в очередь:
_highPriorityQueue.Enqueue( () => Foo() );
_lowPriorityQueue.Enqueue( () => Bar() );
Для выключения:
source.Cancel();
await Task.WhenAll( threads );