> However, the RegisterWaitForSingleObject() method requires an
> instance of
> the WaitHandle class as argument. How do I come from the
> IntPtr that is
> returned by DuplicateHandle() to a WaitHandle instance?
>
> For some odd reason the WaitHandle class is abstract, so I
> also need to
> figure out what actual class I must instantiate.
>
Just write your own WaitHandle derivative and, in its constructor or elsewhere,
stash the handle you have in the base class 'Handle' property. Then pass your
custom WaitHandle to the thread pool.
I've pasted in an approximation of what you need below. Note that the code
below automatically duplicates the handle being passed in. The base class
WaitHandle supports the IDisposable/finalize model, and so will take care of
calling the Win32 CloseHandle function to release the duplicated handle. If you
want to pass in a handle that's already been duplicated by out externally, then
add an overloaded constructor that skips the handle duplication part.
public class Win32WaitHandle : WaitHandle
{
public Win32WaitHandle( IntPtr nativeHandle )
{
// Duplicate the incoming handle.
int h = DuplicateHandle(nativeHandle.ToInt32());
// Store the native handle in the base class.
Handle = new IntPtr(h);
}
[ DllImport("kernel32.dll") ]
static extern int GetCurrentProcess();
[ DllImport("kernel32.dll") ]
static extern bool DuplicateHandle( int hSourceProcess, int originalHandle,
int hTargetProcess, out int newHandle,
uint accessFlags, bool inheritHandle,
uint options );
const int DUPLICATE_SAME_ACCESS = 0x00000002; // From WINNT.H.
static int DuplicateHandle( int h )
{
int hCurProcess = GetCurrentProcess();
int newHandle;
if( DuplicateHandle( hCurProcess, h, hCurProcess, out newHandle,
0, false, DUPLICATE_SAME_ACCESS) )
{
return(newHandle);
}
else
{
throw new ApplicationException("Failed to duplicated handle");
}
}
}