Alex Rivera | Logout

Is it safe to signal and immediately close a ManualResetEvent?

Asked 2010-02-25T19:00:07.083
12

I feel like I should know the answer to this, but I'm going to ask anyway just in case I'm making a potentially catastrophic mistake.

The following code executes as expected with no errors/exceptions:

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");
}

Of course, as is usually the case with multi-threaded code, a successful test does not prove that this is actually thread safe. The test also succeeds if I put Close before Set, even though the documentation clearly states that attempting to do anything after a Close will result in undefined behaviour.

My question is, when I invoke the ManualResetEvent.Set method, is it guaranteed to signal all waiting threads before returning control to the caller? In other words, assuming that I'm able to guarantee that there will be no further calls to WaitOne, is it safe to close the handle here, or is it possible that under some circumstances this code would prevent some waiters from getting signaled or result in an ObjectDisposedException?

The documentation only says that Set puts it in a "signaled state" - it doesn't seem to make any claims about when waiters will actually get that signal, so I'd like to be sure.

Edit
Report

1 Answer

0

Looks like a risky pattern to me, even if due to the [current] implementation, it is OK. you are trying to dispose a resource which may still be in use.

It is like newing and constructing an object and deleting it blindly even before consumers of that object is done.

Even otherwise there is a problem here. Program may exit, even before other threads ever got a chance to run. Thread pool threads are background threads.

Given that you have to wait for other threads anyway, you might as well clean up afterwards.

answered 2010-02-26T08:36:31.163

Your Answer