• 异步读写数据流


    一、异步读取数据

    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();
                }
            }
    
  • 相关阅读:
    git 管理
    SVN 管理
    为什么要做静态库
    Sqlite3
    CocoaPod
    内存管理
    readline的用法
    join合并字符串时使用生成器表达式
    pandas DataFrame数据转为list
    Jenkins自动化CI CD流水线之4--Master-Slave架构
  • 原文地址:https://www.cnblogs.com/wywnet/p/4763693.html
Copyright © 2020-2023  润新知