Internal class, wraps Overlapped structure, completion port callback and IAsyncResult
Inheritance: IAsyncResult, IDisposable
		/// <summary>
		/// Begins an asynchronous unbuffered read operation
		/// </summary>
		/// <param name="pBuffer">The unmanaged buffer to read the data into. 
		/// Buffer should be aligned in memory to device sector size boundary. 
		/// Buffer should not be deallocated or moved until operation is completed.</param>
		/// <param name="fileOffset">File pointer</param>
		/// <param name="numberOfBytesToRead">The maximum number of bytes to read.</param>
		/// <param name="callback">An optional asynchronous callback, to be called when the read is complete.</param>
		/// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
		/// <returns>An IAsyncResult that represents the asynchronous read, which could still be pending.</returns>
		public IAsyncResult BeginRead(IntPtr pBuffer, UInt64 fileOffset, UInt32 numberOfBytesToRead, AsyncCallback callback, object state) {
			if (pBuffer == IntPtr.Zero)
				throw new ArgumentNullException("pBuffer");
			CheckNotDisposed();

			AsyncJob job = null;
			try {
				job = new AsyncJob(callback, state, fileOffset, null);
				UInt32 numberOfBytesRead; bool result;
				unsafe {
					result = NativeMethods.ReadFile(_handle, pBuffer, numberOfBytesToRead, out numberOfBytesRead, job.OverlappedPtr);
				}

				if (result)
					job.CompleteSynchronously();
				else
					CheckErrorPending();

				AsyncJob ret = job; job = null;
				return ret;
			} finally {
				if (job != null)
					job.Dispose();
			}
		}
        /// <summary>
        /// Retrieves data from an array of buffers and writes the data to a file.
        /// </summary>
        /// <param name="segments">Array of pointers to data buffers.
        /// Each buffer must be at least the size of a system memory page and must be aligned
        /// on a system memory page size boundary <seealso cref="SystemPageSize"/>.
        /// The system writes one system memory page of data into each buffer.
        /// Buffers should not be deallocated or moved until operation is completed.</param>
        /// <param name="fileOffset">File pointer</param>
        /// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param>
        /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param>
        /// <returns>An IAsyncResult that represents the asynchronous write, which could still be pending.</returns>
        public IAsyncResult BeginWriteGather(
            IntPtr[] segments,
            UInt64 fileOffset,
            AsyncCallback callback,
            object state)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            CheckNotDisposed();

            NativeMethods.FILE_SEGMENT_ELEMENT[] nativeSegments = new NativeMethods.FILE_SEGMENT_ELEMENT[segments.Length + 1];
            for (int i = 0; i < segments.Length; i++)
            {
                nativeSegments[i].Buffer = segments[i];
            }

            UInt32 numberOfBytesToWrite = (uint)segments.Length * _systemPageSize;

            AsyncJob job = null;

            try
            {
                job = new AsyncJob(callback, state, fileOffset, nativeSegments);
                bool result;
                unsafe
                {
                    fixed(NativeMethods.FILE_SEGMENT_ELEMENT *ps = &nativeSegments[0])
                    {
                        result = NativeMethods.WriteFileGather(_handle, ps, numberOfBytesToWrite, IntPtr.Zero, job.OverlappedPtr);
                    }
                }

                if (result)
                {
                    job.CompleteSynchronously();
                }
                else
                {
                    CheckErrorPending();
                }

                AsyncJob ret = job; job = null;
                return(ret);
            }
            finally
            {
                if (job != null)
                {
                    job.Dispose();
                }
            }
        }
        public bool GetOverlappedResult(IAsyncResult ar, out uint bytes, bool wait)
        {
            CheckNotDisposed();
            AsyncJob job = ar as AsyncJob;

            if (job == null)
            {
                throw new ArgumentException("Invalid argument", "asyncResult");
            }
            unsafe {
                return(NativeMethods.GetOverlappedResult(_handle, job.OverlappedPtr, out bytes, wait));
            }
        }
示例#4
0
        /// <summary>
        /// Begins an asynchronous read operation
        /// </summary>
        /// <param name="buffer">The buffer to read the data into.</param>
        /// <param name="fileOffset">File pointer</param>
        /// <param name="offset">The byte offset in buffer at which to begin writing.</param>
        /// <param name="count">The maximum number of bytes to read.</param>
        /// <param name="callback">An optional asynchronous callback, to be called when the read is complete.</param>
        /// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
        /// <returns>An IAsyncResult that represents the asynchronous read, which could still be pending.</returns>
        public IAsyncResult BeginRead(
            byte[] buffer,
            long fileOffset,
            int offset,
            int count,
            AsyncCallback callback,
            object state
            )
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            CheckNotDisposed();
            AsyncJob job = null;

            try
            {
                job = new AsyncJob(callback, state, (ulong)fileOffset, buffer);
                UInt32 numberOfBytesRead; bool result;
                unsafe
                {
                    fixed(byte *pb = &buffer[offset])
                    {
                        result = NativeMethods.ReadFile(_handle, new IntPtr(pb), (uint)count, out numberOfBytesRead, job.OverlappedPtr);
                    }
                }

                if (result)
                {
                    job.CompleteSynchronously();
                }
                else
                {
                    CheckErrorPending();
                }

                AsyncJob ret = job; job = null;
                return(ret);
            }
            finally
            {
                if (job != null)
                {
                    job.Dispose();
                }
            }
        }
        /// <summary>
        /// Waits for the pending asynchronous operation to complete and frees resources.
        /// </summary>
        /// <param name="ar">The reference to the pending asynchronous request to wait for.</param>
        /// <param name="throwOnError">When true, method throws <see cref="OverlappedStreamException"/> if any error detected.</param>
        /// <returns>Number of bytes transferred</returns>
        public static UInt32 EndOperation(IAsyncResult ar, bool throwOnError)
        {
            AsyncJob job = ar as AsyncJob;

            if (job == null)
            {
                throw new ArgumentException("Invalid argument", "asyncResult");
            }

            job.WaitForCompletion();
            if (throwOnError)
            {
                ASSERT(job.ErrorCode == 0, unchecked ((int)job.ErrorCode));
            }
            return(job.NumberOfBytesTransferred);
        }
        /// <summary>
        /// Begins an asynchronous unbuffered read operation
        /// </summary>
        /// <param name="pBuffer">The unmanaged buffer to read the data into.
        /// Buffer should be aligned in memory to device sector size boundary.
        /// Buffer should not be deallocated or moved until operation is completed.</param>
        /// <param name="fileOffset">File pointer</param>
        /// <param name="numberOfBytesToRead">The maximum number of bytes to read.</param>
        /// <param name="callback">An optional asynchronous callback, to be called when the read is complete.</param>
        /// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
        /// <returns>An IAsyncResult that represents the asynchronous read, which could still be pending.</returns>
        public IAsyncResult BeginRead(IntPtr pBuffer, UInt64 fileOffset, UInt32 numberOfBytesToRead, AsyncCallback callback, object state)
        {
            if (pBuffer == IntPtr.Zero)
            {
                throw new ArgumentNullException("pBuffer");
            }
            CheckNotDisposed();

            AsyncJob job = null;

            try
            {
                job = new AsyncJob(callback, state, fileOffset, null);
                UInt32 numberOfBytesRead; bool result;
                unsafe
                {
                    result = NativeMethods.ReadFile(_handle, pBuffer, numberOfBytesToRead, out numberOfBytesRead, job.OverlappedPtr);
                }

                if (result)
                {
                    job.CompleteSynchronously();
                }
                else
                {
                    CheckErrorPending();
                }

                AsyncJob ret = job; job = null;
                return(ret);
            }
            finally
            {
                if (job != null)
                {
                    job.Dispose();
                }
            }
        }
        /// <summary>
        /// Begins an asynchronous read operation
        /// </summary>
        /// <param name="buffer">The buffer to read the data into.</param>
        /// <param name="fileOffset">File pointer</param>
        /// <param name="offset">The byte offset in buffer at which to begin writing.</param>
        /// <param name="count">The maximum number of bytes to read.</param>
        /// <param name="callback">An optional asynchronous callback, to be called when the read is complete.</param>
        /// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
        /// <returns>An IAsyncResult that represents the asynchronous read, which could still be pending.</returns>
        public IAsyncResult BeginRead(
            byte[] buffer,
            long fileOffset,
            int offset,
            int count,
            AsyncCallback callback,
            object state
        )
        {
            if (buffer == null)
                throw new ArgumentNullException("buffer");
            CheckNotDisposed();
            AsyncJob job = null;
            try
            {
                job = new AsyncJob(callback, state, (ulong)fileOffset, buffer);
                UInt32 numberOfBytesRead; bool result;
                unsafe
                {
                    fixed (byte* pb = &buffer[offset])
                    {
                        result = NativeMethods.ReadFile(_handle, new IntPtr(pb), (uint)count, out numberOfBytesRead, job.OverlappedPtr);
                    }
                }

                if (result)
                    job.CompleteSynchronously();
                else
                    CheckErrorPending();

                AsyncJob ret = job; job = null;
                return ret;
            }
            finally
            {
                if (job != null)
                    job.Dispose();
            }
        }
		/// <summary>
		/// Retrieves data from an array of buffers and writes the data to a file.
		/// </summary>
		/// <param name="segments">Array of pointers to data buffers. 
		/// Each buffer must be at least the size of a system memory page and must be aligned 
		/// on a system memory page size boundary <seealso cref="SystemPageSize"/>. 
		/// The system writes one system memory page of data into each buffer. 
		/// Buffers should not be deallocated or moved until operation is completed.</param>
		/// <param name="fileOffset">File pointer</param>
		/// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param>
		/// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param>
		/// <returns>An IAsyncResult that represents the asynchronous write, which could still be pending.</returns>
		public IAsyncResult BeginWriteGather(
				IntPtr[] segments,
				UInt64 fileOffset,
				AsyncCallback callback,
				object state) {
			if (segments == null)
				throw new ArgumentNullException("segments");
			CheckNotDisposed();

			NativeMethods.FILE_SEGMENT_ELEMENT[] nativeSegments = new NativeMethods.FILE_SEGMENT_ELEMENT[segments.Length + 1];
			for (int i = 0; i < segments.Length; i++)
				nativeSegments[i].Buffer = segments[i];

			UInt32 numberOfBytesToWrite = (uint)segments.Length * _systemPageSize;

			AsyncJob job = null;
			try {
				job = new AsyncJob(callback, state, fileOffset, nativeSegments);
				bool result;
				unsafe {
					fixed (NativeMethods.FILE_SEGMENT_ELEMENT* ps = &nativeSegments[0]) {
						result = NativeMethods.WriteFileGather(_handle, ps, numberOfBytesToWrite, IntPtr.Zero, job.OverlappedPtr);
					}
				}

				if (result)
					job.CompleteSynchronously();
				else
					CheckErrorPending();

				AsyncJob ret = job; job = null;
				return ret;
			} finally {
				if (job != null)
					job.Dispose();
			}
		}