private long _result;                  // Using long since this needs to be used in Interlocked APIs

        // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
        internal FileStreamCompletionSource(IFileStreamCompletionSourceStrategy strategy, PreAllocatedOverlapped?preallocatedOverlapped,
                                            int numBufferedBytes, byte[]?bytes) : base(TaskCreationOptions.RunContinuationsAsynchronously)
        {
            _numBufferedBytes = numBufferedBytes;
            _strategy         = strategy;
            _result           = NoResult;

            // The _preallocatedOverlapped is null if the internal buffer was never created, so we check for
            // a non-null bytes before using the stream's _preallocatedOverlapped
            _overlapped = bytes != null && strategy.CompareExchangeCurrentOverlappedOwner(this, null) == null ?
                          strategy.FileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(preallocatedOverlapped !) : // allocated when buffer was created, and buffer is non-null
                          strategy.FileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(s_ioCallback, this, bytes);
            Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null");
        }
        internal virtual void ReleaseNativeResource()
        {
            // Ensure that cancellation has been completed and cleaned up.
            _cancellationRegistration.Dispose();

            // Free the overlapped.
            // NOTE: The cancellation must *NOT* be running at this point, or it may observe freed memory
            // (this is why we disposed the registration above).
            if (_overlapped != null)
            {
                _strategy.FileHandle.ThreadPoolBinding !.FreeNativeOverlapped(_overlapped);
                _overlapped = null;
            }

            // Ensure we're no longer set as the current completion source (we may not have been to begin with).
            // Only one operation at a time is eligible to use the preallocated overlapped,
            _strategy.CompareExchangeCurrentOverlappedOwner(null, this);
        }