У меня есть очередь заданий, которые могут быть заполнены несколькими потоками (ConcurrentQueue<MyJob>
). Мне нужно реализовать непрерывное выполнение этих заданий асинхронно (не по основному потоку), но только одним потоком в то же время. Я пытался что-то вроде этого:Многопоточная очередь заданий
public class ConcurrentLoop {
private static ConcurrentQueue<MyJob> _concurrentQueue = new ConcurrentQueue<MyJob>();
private static Task _currentTask;
private static object _lock = new object();
public static void QueueJob(Job job)
{
_concurrentQueue.Enqueue(job);
checkLoop();
}
private static void checkLoop()
{
if (_currentTask == null || _currentTask.IsCompleted)
{
lock (_lock)
{
if (_currentTask == null || _currentTask.IsCompleted)
{
_currentTask = Task.Run(() =>
{
MyJob current;
while(_concurrentQueue.TryDequeue(out current))
//Do something
});
}
}
}
}
}
Этот код на мой взгляд, есть проблема: если задача finnishing выполнить (TryDequeue
возвращает ложь, но задача не была помечена как доделаю), и в этот момент я получаю новая работа, она не будет выполнена. Я прав? Если да, то как это исправить?
Есть ли настоящая причина, по которой вы пытаетесь ограничить количество потоков? Лучше разрешить оптимизацию обработки фреймов для вас большую часть времени. – konkked
Используйте Lock на блоке кода, который вы хотите исполнять по одному потоку за раз. Это должно решить проблему. – Reddy
замок с 'ConcurrentQueue'? Я верю, что есть лучший способ – xalz