Я читал документацию AutoResetEvent на MSDN, и следующее предупреждение меня беспокоит.
"Важно:
Нет никакой гарантии, что каждый вызов метода Set освободит поток. Если два вызова находятся слишком близко друг к другу, так что второй вызов происходит до освобождения потока, освобождается только один поток. Как будто второго звонка не произошло. Также, если Set вызывается, когда нет ожидающих потоков и AutoResetEvent уже сигнализирован, вызов не имеет никакого эффекта. "
Но это предупреждение в основном убивает саму причину использования таких методов синхронизации потоков. Например, у меня есть список, который будет содержать вакансии. И есть только один производитель, который добавит вакансии в список. У меня есть потребители (более одного), которые ждут, чтобы получить работу из списка .. как-то так ..
Производитель:
void AddJob(Job j)
{
lock(qLock)
{
jobQ.Enqueue(j);
}
newJobEvent.Set(); // newJobEvent is AutoResetEvent
}
Потребитель
void Run()
{
while(canRun)
{
newJobEvent.WaitOne();
IJob job = null;
lock(qLock)
{
job = jobQ.Dequeue();
}
// process job
}
}
Если приведенное выше предупреждение верно, то, если я очень быстро поставлю в очередь два задания, только один поток получит задание, не так ли? Я предполагал, что Set будет атомарным, то есть он делает следующее:
- Установить событие
- Если потоки ожидают, выберите одну из них, чтобы разбудить
- сброс события
- запустить выбранный поток.
Так что я в основном озадачен предупреждением в MSDN. это действительное предупреждение?