Работая над большим проектом, я понял, что планирую сделать много звонков в будущем.Поскольку они были довольно легковесными, я подумал, что может быть лучше использовать отдельный планировщик.
ThreadPool.QueueUserWorkItem (() =>
{
Thread.Sleep (5000);
Foo (); // Call is to be executed after sometime
});
Поэтому я создал отдельный класс планировщика, который запускается в своем собственном потоке и выполняет эти события.У меня есть 2 функции, которые получают доступ к общей очереди из отдельных потоков.Я бы использовал блокировку, но так как один из потоков должен находиться в режиме ожидания, я не знал, как снять блокировку.
class Scheduler
{
SortedDictionary <DateTime, Action> _queue;
EventWaitHandle _sync;
// Runs on its own thread
void Run ()
{
while (true)
{
// Calculate time till first event
// If queue empty, use pre-defined value
TimeSpan timeDiff = _queue.First().Key - DateTime.Now;
// Execute action if in the next 100ms
if (timeDiff < 100ms)
...
// Wait on event handle for time
else
_sync.WaitOne (timeDiff);
}
}
// Can be called by any thread
void ScheduleEvent (Action action, DataTime time)
{
_queue.Add (time, action);
// Signal thread to wake up and check again
_sync.Set ();
}
}
Проблема в том, что я неУверен, как синхронизировать доступ к очереди между двумя функциями.Я не могу использовать монитор или мьютекс, потому что Run () будет спать-ждать, вызывая тем самым тупик.Какой механизм синхронизации использовать здесь?(Если существует механизм для атомарного запуска процесса ожидания и немедленного снятия блокировки, это может решить мою проблему) Как я могу убедиться в отсутствии состояния гонки? Является ли это разновидностью проблемы потребителя производителя, или есть более актуальное описание проблемы синхронизации?Хотя это несколько ориентировано на C #, я был бы рад услышать общее решение этого вопроса.Спасибо!