Рассмотрите возможность использования Monitor.Wait()
и Monitor.Pulse()
.
Например:
object locker = new object();
private void Run()
{
while (!_isQuitting)
{
lock (locker)
{
Monitor.Wait(locker);
DoStuff(jobData);
}
}
DoCleanupStuff();
}
public void AddJob(object param)
{
// Obtain the lock first so that you don’t
// change jobData while the thread is processing it
lock (locker)
{
jobData = param;
Monitor.Pulse(locker);
}
}
public void Stop()
{
lock (locker)
{
_isQuitting = true;
Monitor.Pulse(locker);
}
// Wait for the thread to finish — no need for _isFinished
_thread.Join();
}
Однако обратите внимание, что в моем коде у вас все еще есть только один объект jobData
- в результате AddJob()
будет ожидать завершения текущей работы. Это может быть не то, что вы хотите. Возможно, у вас должно быть Queue<T>
объектов данных задания; AddJob
будет Enqueue
элемент, а Run
будет держать Dequeue
, пока очередь не станет пустой. Если вы сделаете это, оператор блокировки в Run
должен охватывать только доступ к очереди, а не весь этап обработки.