public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
        {
            if (handle == null)
                throw new ArgumentNullException("handle");

            if (handle.IsClosed || handle.IsInvalid)
                throw new ArgumentException(SR.Argument_InvalidHandle, "handle");

            // Make sure we use a statically-rooted completion callback, 
            // so it doesn't get collected while the I/O is in progress.
            Interop.NativeIoCompletionCallback callback = s_nativeIoCompletionCallback;
            if (callback == null)
                s_nativeIoCompletionCallback = callback = new Interop.NativeIoCompletionCallback(OnNativeIOCompleted);

            SafeThreadPoolIOHandle threadPoolHandle = Interop.mincore.CreateThreadpoolIo(handle, s_nativeIoCompletionCallback, IntPtr.Zero, IntPtr.Zero);
            if (threadPoolHandle.IsInvalid)
            {
                int hr = Marshal.GetHRForLastWin32Error();
                if (hr == System.HResults.E_HANDLE)         // Bad handle
                    throw new ArgumentException(SR.Argument_InvalidHandle, "handle");

                if (hr == System.HResults.E_INVALIDARG)     // Handle already bound or sync handle
                    throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, "handle");

                throw Marshal.GetExceptionForHR(hr);
            }

            return new ThreadPoolBoundHandle(handle, threadPoolHandle);
        }
        public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
        {
            if (handle == null)
            {
                throw new ArgumentNullException("handle");
            }

            if (handle.IsClosed || handle.IsInvalid)
            {
                throw new ArgumentException(SR.Argument_InvalidHandle, "handle");
            }

            // Make sure we use a statically-rooted completion callback,
            // so it doesn't get collected while the I/O is in progress.
            Interop.NativeIoCompletionCallback callback = s_nativeIoCompletionCallback;
            if (callback == null)
            {
                s_nativeIoCompletionCallback = callback = new Interop.NativeIoCompletionCallback(OnNativeIOCompleted);
            }

            SafeThreadPoolIOHandle threadPoolHandle = Interop.mincore.CreateThreadpoolIo(handle, s_nativeIoCompletionCallback, IntPtr.Zero, IntPtr.Zero);

            if (threadPoolHandle.IsInvalid)
            {
                int hr = Marshal.GetHRForLastWin32Error();
                if (hr == System.HResults.E_HANDLE)         // Bad handle
                {
                    throw new ArgumentException(SR.Argument_InvalidHandle, "handle");
                }

                if (hr == System.HResults.E_INVALIDARG)     // Handle already bound or sync handle
                {
                    throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, "handle");
                }

                throw Marshal.GetExceptionForHR(hr);
            }

            return(new ThreadPoolBoundHandle(handle, threadPoolHandle));
        }