/// <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(); } } }
/// <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(); } }