Should AutoResetEvent be Disposed explicitly?

  • Thread starter Thread starter Morgan Cheng
  • Start date Start date
M

Morgan Cheng

In order to arrange a time-out operation, I make the task running in a
worker thread; and wait in main thread with AutoResetEvent help. The
code is like below.

AutoResetEvent ev = new AutoResetEvent();
if ( !ThreadPool.QueueUserWorkItem(WorkerProc, ev) )
{
throw new ApplicationException("fail to queue task");
}
ev.WaitOne(5000, false); //timeout == 5000 ms


public void WorkProc(object state)
{
AutoResetEvent ev = state as AutoResetEvent;

// do some timecosting job
.....

ev.Set();

}

However, AutoResetEvent inherits from WaitHandle which inherits from
IDisposable. So, I change mo code to
using (AutoResetEvent ev = new AutoResetEvent() )
{
if ( !ThreadPool.QueueUserWorkItem(WorkerProc, ev) )
{
throw new ApplicationException("fail to queue task");
}
ev.WaitOne(5000, false); //timeout == 5000 ms
};


public void WorkProc(object state)
{
AutoResetEvent ev = state as AutoResetEvent;

// do some timecosting job
.....

ev.Set(); // ObjectDisposedException may be thrown here.

}

While debugging, ObjectDisposedException may be thrown from WokProc,
because AutoResetEvent might have been disposed in main thread. So,
have to embrace ev.Set with try{} catch {} to get
ObjectDisposedException. It is ugly code.

So, what is best solution?
 
While debugging, ObjectDisposedException may be thrown from WokProc,
because AutoResetEvent might have been disposed in main thread. So,
have to embrace ev.Set with try{} catch {} to get
ObjectDisposedException. It is ugly code.

So, what is best solution?

IMHO, it's a bad idea to have a situation in which you attempt to dispose
an object before you know that every other thread is done with it. IMHO,
it's also a bad idea to just give up on a thread, even in the event of a
timeout.

It's fine to have the timeout, but if you're going to do that, you need a
mechanism by which the worker thread and the main thread communicate
status before disposing the event. If you do that, then you won't have a
situation in which the main thread has already disposed the exception
before the worker thread tries to use it.

Pete
 
IMHO, it's a bad idea to have a situation in which you attempt to dispose
an object before you know that every other thread is done with it. IMHO,
it's also a bad idea to just give up on a thread, even in the event of a
timeout.

If I tries to add mechanism to sync the disposal of the
AutoResetEvent, I need another AutoResetEvent. Then disposal of that
second AutoResetEvent instance is a problem...

In MSDN sample code, AutoResetEvent is not disposed explicitly.
 
IMHO, it's a bad idea to have a situation in which you attempt to dispose
an object before you know that every other thread is done with it. IMHO,
it's also a bad idea to just give up on a thread, even in the event of a
timeout.

It's fine to have the timeout, but if you're going to do that, you need a
mechanism by which the worker thread and the main thread communicate
status before disposing the event. If you do that, then you won't have a
situation in which the main thread has already disposed the exception
before the worker thread tries to use it.

Pete


Or, we can make the AutoResetEvent always disposed in worker thread
after AutoResetEvent.Set invocation.

AutoResetEvent ev = new AutoResetEvent(false);
if ( !ThreadPool.QueueUserWorkItem(WorkerProc, ev) )
{
throw new ApplicationException("fail to queue task");
}
ev.WaitOne(5000, false); //timeout == 5000 ms


public void WorkProc(object state)
{
AutoResetEvent ev = state as AutoResetEvent;

try
{
// do some timecosting job
.....
}
finally
{
ev.Set();
ev.Close();
}

}
 
Back
Top