异步读写数据流
一、异步读取数据
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; namespace UseBeginRead { class Program { //定义异步读取状态类 class AsyncState { public FileStream FS { get; set; } public byte[] Buffer { get; set; } public ManualResetEvent EvtHandle { get; set; } } static int bufferSize = 512; static void Main(string[] args) { string filePath = "d:\\test.txt"; //以只读方式打开文件流 using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var buffer = new byte[bufferSize]; //构造BeginRead需要传递的状态 var asyncState = new AsyncState { FS = fileStream, Buffer = buffer ,EvtHandle = new ManualResetEvent(false)}; //异步读取 IAsyncResult asyncResult = fileStream.BeginRead(buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState); //阻塞当前线程直到读取完毕发出信号 asyncState.EvtHandle.WaitOne(); Console.WriteLine(); Console.WriteLine("read complete"); Console.Read(); } } //异步读取回调处理方法 public static void AsyncReadCallback(IAsyncResult asyncResult) { var asyncState = (AsyncState)asyncResult.AsyncState; int readCn = asyncState.FS.EndRead(asyncResult); //判断是否读到内容 if (readCn > 0) { byte[] buffer; if (readCn == bufferSize) buffer = asyncState.Buffer; else { buffer = new byte[readCn]; Array.Copy(asyncState.Buffer, 0, buffer, 0, readCn); } //输出读取内容值 string readContent = Encoding.UTF8.GetString(buffer); Console.Write(readContent); } if (readCn < bufferSize) { asyncState.EvtHandle.Set(); } else { Array.Clear(asyncState.Buffer, 0, bufferSize); //再次执行异步读取操作 asyncState.FS.BeginRead(asyncState.Buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState); } } } }
二、异步写入数据
class Program { /// <summary> /// 异步回调需要的参数封装类 /// </summary> class AsyncState { public int WriteCountOnce { get; set; } public int Offset { get; set; } public byte[] Buffer { get; set; } public ManualResetEvent WaitHandle { get; set; } public FileStream FS { get; set; } } static void Main(string[] args) { //准备一个1K的字节数组 byte[] toWriteBytes = new byte[1 << 10]; for (int i = 0; i < toWriteBytes.Length; i++) { toWriteBytes[i] = (byte)(i % byte.MaxValue); } string filePath = "d:\\test.txt"; //FileStream实例 using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { int offset = 0; //每次写入32字节 int writeCountOnce = 1 << 5; //构造回调函数需要的状态 AsyncState state = new AsyncState{ WriteCountOnce = writeCountOnce, Offset = offset, Buffer = toWriteBytes, WaitHandle = new ManualResetEvent(false), FS = fileStream }; //做异步写操作 fileStream.BeginWrite(toWriteBytes, offset, writeCountOnce, WriteCallback, state); //等待写完毕或者出错发出的继续信号 state.WaitHandle.WaitOne(); } Console.WriteLine("Done"); Console.Read(); } /// <summary> /// 异步写的回调函数 /// </summary> /// <param name="asyncResult">写状态</param> static void WriteCallback(IAsyncResult asyncResult) { AsyncState state = (AsyncState)asyncResult.AsyncState; try { state.FS.EndWrite(asyncResult); } catch (Exception ex) { Console.WriteLine("EndWrite Error:" + ex.Message); state.WaitHandle.Set(); return; } Console.WriteLine("write to " + state.FS.Position); //判断是否写完,未写完继续异步写 if (state.Offset + state.WriteCountOnce < state.Buffer.Length) { state.Offset += state.WriteCountOnce; Console.WriteLine("call BeginWrite again"); state.FS.BeginWrite(state.Buffer, state.Offset, state.WriteCountOnce, WriteCallback, state); } else { //写完发出完成信号 state.WaitHandle.Set(); } }