É seguro sinalizar e fechar imediatamente um ManualResetEvent?
Sinto que deveria saber a resposta para isso, mas vou perguntar assim mesmo, para o caso de estar cometendo um erro potencialmente catastrófico.
O código a seguir é executado conforme o esperado, sem erros / exceções:
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");
}
Obviamente, como geralmente ocorre com o código multithread, um teste bem-sucedido não prova que isso é realmente seguro para threads. O teste também terá êxito se eu colocarClose
antesSet
, mesmo que a documentação indique claramente que a tentativa de fazer qualquer coisa após umClose
resultará em comportamento indefinido.
Minha pergunta é, quando invoco oManualResetEvent.Set
método, é garantido sinalizartudo threads em esperaantes retornando o controle para o chamador? Em outras palavras, supondo que eu seja capaz de garantir que não haverá mais chamadas paraWaitOne
, é seguro fechar o identificador aqui ou é possível que, em algumas circunstâncias, esse código impeça que alguns garçons sejam sinalizados ou resultem em umaObjectDisposedException
?
A documentação diz apenas queSet
coloca-o em um "estado sinalizado" - não parece fazer nenhuma reivindicação sobre quando os garçons irãorealmente pegue esse sinal, então eu gostaria de ter certeza.