Should AutoResetEvent be Disposed explicitly?

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?
 
P

Peter Duniho

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
 
M

Morgan Cheng

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.
 
M

Morgan Cheng

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

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top