示例#1
0
        static unsafe void FinishOverlappedAsynchronously(SafeObjectHandle handle, PinnedStruct <OVERLAPPED> overlapped,
                                                          ManualResetEvent finishedEvent, TaskCompletionSource <int> completionSource, CancellationToken cancellationToken)
        {
            var alreadyFinished          = false;
            var lockObject               = new object();
            WaitOrTimerCallback callback = (state, timedOut) =>
            {
                var overlappedState = (OverlappedState)state;
                lock (lockObject)
                {
                    if (alreadyFinished)
                    {
                        return;
                    }

                    overlappedState.Unregister();

                    if (overlappedState.IsCancellation || cancellationToken.IsCancellationRequested)
                    {
                        CancelIoEx(handle, (OVERLAPPED *)overlapped.Pointer);
                        completionSource.SetCanceled();
                    }
                    else
                    {
                        int bytesReturned;
                        var overlappedResult = GetOverlappedResult(handle, (OVERLAPPED *)overlapped.Pointer,
                                                                   out bytesReturned, false);

                        overlapped.Dispose();
                        finishedEvent.Dispose();

                        if (overlappedResult)
                        {
                            completionSource.SetResult(bytesReturned);
                        }
                        else
                        {
                            SetFromLastWin32Exception(completionSource);
                        }
                    }

                    alreadyFinished = true;
                }
            };

            lock (lockObject)
            {
                var finishedState  = new OverlappedState(false);
                var cancelledState = new OverlappedState(true);
                var finishedWait   = ThreadPool.RegisterWaitForSingleObject(finishedEvent, callback, finishedState, -1, true);
                cancelledState.OtherRegistration = finishedWait;
                if (cancellationToken != CancellationToken.None)
                {
                    var cancelledWait = ThreadPool.RegisterWaitForSingleObject(cancellationToken.WaitHandle,
                                                                               callback,
                                                                               cancelledState, -1, true);
                    finishedState.OtherRegistration = cancelledWait;
                }
            }
        }
示例#2
0
        static unsafe bool FinishOverlappedSynchronously(SafeObjectHandle handle, CancellationToken cancellationToken,
                                                         PinnedStruct <OVERLAPPED> overlapped, TaskCompletionSource <int> completionSource, bool nativeMethodResult)
        {
            if (!nativeMethodResult)
            {
                var error = Marshal.GetLastWin32Error();
                if (error != ErrorIoPending)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        completionSource.SetCanceled();
                    }
                    else
                    {
                        SetFromLastWin32Exception(completionSource);
                    }

                    return(true);
                }

                // Async IO in progress
                return(false);
            }

            int pBytesReturned;

            GetOverlappedResult(handle, (OVERLAPPED *)overlapped.Pointer,
                                out pBytesReturned, false);
            if (cancellationToken.IsCancellationRequested)
            {
                completionSource.SetCanceled();
            }
            else
            {
                completionSource.SetResult(pBytesReturned);
            }

            return(true);
        }