Mladen Prajdić Blog

Blog about stuff and things and stuff. Mostly about SQL server and .Net

Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle

I had to convert a project from .Net 1.1 to .Net 2.0 this week.
It built ok with a few warnings. Amongst others there was this one:
Warning: 'System.Threading.WaitHandle.Handle' is obsolete: 'Use the SafeWaitHandle property instead.'

That's cool, no problem, right? As it turns out it's not just replacing one property with another.
Handle property is IntPtr type and SafeWaitHandle is a class.
So .Net 2.0 has a new class called SafeWaitHandle which represents a wrapper class for a wait handle.
Why it's there is well explained on BCLTeam's blogs here.

So what to do?

It preety simple in the end.
instead of
_Event.Handle;
just use
_Event.SafeWaitHandle.DangerousGetHandle();

where _Event is in my case AutoResetEvent type.

Legacy Comments


Thomas Patten
2007-06-27
re: Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle
I would like to thank you for your post. I was trying to update a DirectSound example and ran into this problem. Your solution seemed to do the trick.

Thomas Patten

Mladen
2007-06-27
re: Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle
you're welcome.

Jan Palmer
2007-09-05
re: Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle
Hello,

May I ask if using the .SafeWaitHandle.DangerousGetHandle would release the handle of the AutoResetEvent?

I have a problem of doing this piece of code:
***********************
For my main Program.cs:
***********************
for (int i = 0; i < JobNumber; i++)
{
doneEvents[i] = new AutoResetEvent(false);
if (i + 1 == JobNumber) jobqueue = true;
JobProcess f = new JobProcess(r.Next(20, 40), doneEvents[i], jobqueue);
arrJob[i] = f;
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);

}

WaitHandle.WaitAll(doneEvents);
Console.WriteLine("Process stops here");
...

***********************
For my calling class JobProcess.cs:
***********************

public void ThreadPoolCallback(Object threadContext)
{ int threadIndex = (int)threadContext;
Console.WriteLine("job thread {0} started... at n:{1}", threadIndex, _n);
_JobN = Calculate(_n);
Console.WriteLine("job thread {0} result calculated...", threadIndex);
/*_doneEvent.Set(); */
if (_endOfJobQueue == true)
{ _doneEvent.SafeWaitHandle.SetHandleAsInvalid();
_doneEvent.SafeWaitHandle.DangerousGetHandle();
//SafeWaitHandle.DangerousRelease();
Console.WriteLine(" is closed?: " + _doneEvent.SafeWaitHandle.IsClosed.ToString() +
"\r\n timeout:" + WaitHandle.WaitTimeout.ToString());
}
else{
_doneEvent.WaitOne();
}
}


What I am trying to do is to set QueueUserWorkItem to run the ThreadPoolCallback in such a way I will do synchronization. But the problem when I run my code. It never reached the Console.WriteLine("Process stops here")


where as if I comment the
if (_endOfJobQueue == true)
{ ... }
else{
_doneEvent.WaitOne();
}

and replaced is by just _doneEvent.Set(); It works and it reaches the Console.WriteLine("Process stops here") but the synchronization of the _doneEvent is not observed.

What I want to attain is how to release, or perhaps signal the WaitHandle.WaitAll() that there is nothing more to wait but proceed to exit and close the thread queue.

Thank You.

Mladen
2007-09-05
re: Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle
no idea on that one Jan.
look with reflector what it does under the hood.

chan
2008-03-03
re: Converting System.Threading.WaitHandle.Handle to System.Threading.WaitHandle.SafeWaitHandle
You can use the SafeWaitHandle.DangerousGetHandle method. So your code will look like this:


wo.hEvent = writeEvent.SafeWaitHandle.DangerousGetHandle();



If you want to know why, please read this blog from Brian Grunkemeyer: SafeHandle: A Reliability Case Study.

http://blogs.msdn.com/bclteam/archive/2005/03/16/396900.aspx