Безопасно ли сигнализировать и немедленно закрыть ManualResetEvent?
Я чувствую, что должен знать ответ на этот вопрос, но я все равно спрошу на всякий случай, если сделаю потенциально катастрофическую ошибку.
Следующий код выполняется должным образом без ошибок / исключений:
static void Main(string[] args)
{
ManualResetEvent flag = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(s =>
{
flag.WaitOne();
Console.WriteLine("Work Item 1 Executed");
});
ThreadPool.QueueUserWorkItem(s =>
{
flag.WaitOne();
Console.WriteLine("Work Item 2 Executed");
});
Thread.Sleep(1000);
flag.Set();
flag.Close();
Console.WriteLine("Finished");
}
Конечно, как это обычно бывает с многопоточным кодом, успешное тестирование не доказывает, что это на самом деле потокобезопасно. Тест также будет успешным, если я поставлюClose
доSet
, хотя в документации четко указано, что попытка сделать что-либо послеClose
приведет к неопределенному поведению.
Мой вопрос, когда я призываюManualResetEvent.Set
метод, это гарантирует сигналвсе ожидающие темыдо вернуть контроль звонящему? Другими словами, при условии, что я могу гарантировать, что больше не будет звонковWaitOne
, безопасно ли здесь закрывать дескриптор, или возможно, что при некоторых обстоятельствах этот код будет препятствовать тому, чтобы официанты получили сигнал, или приведет кObjectDisposedException
?
Документация только говорит, чтоSet
переводит его в «сигнальное состояние» - он, кажется, не претендует на то, когда официантына самом деле получить этот сигнал, так что я хотел бы быть уверен.