나는 이것에 대한 답을 알아야만한다고 생각하지만, 어쨌든 내가 잠재적으로 치명적인 실수를 저지르고있는 경우에 대비하여 어쨌든 질문 할 것입니다.신호를 보내고 즉시 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
앞에 넣어도 테스트가 성공합니다. 나는 ManualResetEvent.Set
메소드를 호출 할 때
내 질문은, 그것이 호출자에게 제어를 반환 전에 모든 대기 스레드 신호 보장이다? 다시 말해서 WaitOne
에 더 이상 전화가 걸리지 않는다고 보장 할 수 있다고 가정 할 때 여기서 핸들을 닫는 것이 안전 할 수도 있고 어떤 경우에는이 코드가 일부 웨이터의 신호 또는 결과를 방해 할 수도 있습니다 ObjectDisposedException
에? 이 웨이터가 실제로 신호 얻을 것이다 경우에 대한 주장을하지 않는 것, 그래서 나는 확인하고 싶습니다 -
문서는 Set
는 "이 상태를 신호"에두고 있다고 말한다.
흥미로운 실험은 WaitOne() 직전에 Sleep을 이동하는 것입니다. 이렇게하면 'flag'가 Close() '일 때 WaitOne()이 수행하는 작업을 테스트 할 수 있습니다. –
@ Philh Ngan : 문서에서 알 수 있듯이 실제로는 정의되지 않았습니다. 'Thread.Sleep' 전에 코드에서'Close'를 움직이면'WaitOne' 중에'ObjectDisposedException' ("안전 핸들이 닫혔습니다")을 얻습니다. 반면,'Thread.Sleep' 이후에 직접 Close *를 움직이면, 두 스레드 모두 신호를 받고 성공적으로 실행이 완료됩니다. 따라서 정의되지 않은 동작에는 "불량"코드에 경쟁 조건이 있습니다. 난 그냥 내 "좋은"코드라고 생각하는 것과 비슷한 정의되지 않은 동작을하지 않기를 원한다. :) – Aaronaught