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 |