异步编程-异步读取文件

版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/84678110

这篇文章我们学习如何用异步编程来读取文件。

使用System.IO.Stream类的异步调用方法,对文件out.txt进行异步读操作。

运行结果:

源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Contexts;
using System.IO;

namespace Test1_1
{
    class HelloWorld
    {
        static void Main(string[] args)
        {
            //实例化异步I/O测试器
            AsynchIOTester theApp = new AsynchIOTester("D:\\out.txt");
            //创建回调委托对象
            AsyncCallback myCallBack = new AsyncCallback(OnReadDone);
            //开始异步读操作
            IAsyncResult ar = theApp.InputStream.BeginRead(
                theApp.Buffer,                                                      //存放结果的缓存
                0,                                                                  //偏移值
                theApp.Buffer.Length,                                               //缓冲大小
                myCallBack,                                                         //回调方法
                theApp);                                                            //局部状态对象
            Console.WriteLine("++++++主线程继续工作+++++");
            Thread.Sleep(1000);
            Console.WriteLine("\n\n++++++++主线程工作完成,执行了1秒,等待异步调用完成\n");

            Console.Read();
        }
        //回调方法
        static void OnReadDone(IAsyncResult ar)
        {
            //获取局部状态对象
            AsynchIOTester test = (AsynchIOTester)ar.AsyncState; 
            //结束异步读操作,返回读取的字节数
            int bufferCount = test.InputStream.EndRead(ar);

            if (bufferCount > 0)
            {
                //模拟下一次读取间隔0.1s,以免较快读完
                Thread.Sleep(100);
                //转换成指对编码的字符串
                string s = Encoding.GetEncoding("GB2312").GetString(test.Buffer, 0, bufferCount);
                Console.Write(s);
                //创建回调委托对象
                AsyncCallback myCallBack = new AsyncCallback(OnReadDone);
                //如果没有读完,再次异步调用BeginRead
                test.InputStream.BeginRead(test.Buffer, 0, test.Buffer.Length, myCallBack, test);
            }
        }
    }
    //异步I/O测试器
    public class AsynchIOTester
    {
        private Stream inputStream;                         //输入流
        private byte[] buffer;                              //存入读入数据的缓冲区
        private string filename;

        public AsynchIOTester(string filename)              //构造函数
        {
            this.filename = filename;
            inputStream = File.OpenRead(filename);          //打开文件
            buffer = new byte[16];                          //分配缓冲
        }

        public byte[] Buffer
        {
            get { return buffer; }
        }

        public Stream InputStream
        {
            get { return inputStream ;}
        }
    }
}

主线程首先创建了一个AsynchIOTester异步I/O测试器对象(即theApp)。该对象包括输入流,缓冲区等信息。程序可以在回调时获取它。然后,主线程中声明了一个AsyncCallBack类型的委托对象myCallback,用于创建回调委托对象。该对象绑定了回调方法OnReadDone()。接下来,调用BeginRead()方法,进行文件的异步读取,之后我们使用Thread.Sleep(1000)来模拟需要执行的操作耗时1秒。这时,异步调用已经开始,因为不希望一次异步调用就读完整个文件,因此,将缓冲区设为16个字节。

当读取完成时,CLR将调用回调方法OnReadDone()。在OnReadDone()方法中,我们首先用(AsynchIOTester)ar.AsyncState获取调用开始时封装的异步I/O数。如果字节数大于0,将缓冲转换成字符串并输出,然后再次调用BeginRead,开始下一次异步读取,为避免因为较快读完,而无法验证是否进行了异步调用,我们使用Thread.Sleep(100),使之在0.1秒后再进行下一个操作。

猜你喜欢

转载自blog.csdn.net/baidu_38304645/article/details/84678110