关于异步文件IO

近来由于BOSS提出,网站的速度太慢,要求提高速度,考虑到要读取大量的XML配置文件与HTML静态文件,

因此,想到先从最基本的XML文件读取方面入手,同时,结合网站上提供的一些老外的视频文件,看了一些,

便做了一个异步读取的类,经过试运行后,效果的确有所提高,因此便记录下来,也备后用。当然还有一些可以

优化与改进的地方,没办法,慢慢来吧。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data ;
using System.Data.SqlClient ;
using System.Threading ;
using System.ComponentModel ;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
namespace AsyncIO
{
    public class ReadLargeFileCompletedEventArgs : AsyncCompletedEventArgs
    {
        byte[] _buffer;
        public byte[] Buffer
        {
            get { return _buffer; }
        }
        public ReadLargeFileCompletedEventArgs(byte[] buffer,Exception e,bool canncel,object state)
            : base(e, canncel, state)
        {
            _buffer = buffer;
        }
    }
    public class ReadLargeFileProgressEventArgs : ProgressChangedEventArgs
    {
        int _FileLen;
        int _Reads;
        byte[] buffer;
        public ReadLargeFileProgressEventArgs(int iFileLength, int iHasRead, int Percentage, object state,byte[] _Buffer)
            :
            base(Percentage, state)
        {
            _FileLen = iFileLength;
            _Reads = iHasRead;
            buffer = _Buffer;

        }
        public int FileLength
        {
            get{ return _FileLen ;}
        }
        public int HasRead
        {
            get { return _Reads; }
        }
        public byte[] Buffer
        {
            get { return buffer; }
        }
    }
    public delegate void ReadLargeFileCompletedEventHander(object sender, ReadLargeFileCompletedEventArgs e);
    public delegate void ReadLargeFileProgressEventHandler(object sender ,ReadLargeFileProgressEventArgs e);

    public  class AsyncDataAccess
    {
        internal delegate void WorkerEventHander(string sFilePath, object userToken);

        public event ReadLargeFileCompletedEventHander ReadCompleted;
        public event ReadLargeFileProgressEventHandler ReadProgressChanged;

        HybridDictionary taskToker = new HybridDictionary();

        SendOrPostCallback _complated;
        SendOrPostCallback _reportProgress;
        SendOrPostCallback _completionMethod;
        protected void OnReadCompleted(ReadLargeFileCompletedEventArgs args)
        {
            if (ReadCompleted != null)
                ReadCompleted(this, args);
        }
        protected void OnReadProgressChanged(ReadLargeFileProgressEventArgs args)
        {
            if (ReadProgressChanged != null)
                ReadProgressChanged(this, args);
        }

        public AsyncDataAccess()
        {
            _complated = new SendOrPostCallback(comleted);
            _reportProgress = new SendOrPostCallback(report);
            _completionMethod = new SendOrPostCallback(completionMethod);
        }
        void comleted(object state)
        {
            ReadLargeFileCompletedEventArgs args = state as ReadLargeFileCompletedEventArgs;
            OnReadCompleted(args);
      
        }
        void report(object state)
        {
            ReadLargeFileProgressEventArgs args = state as ReadLargeFileProgressEventArgs;
            OnReadProgressChanged(args);
        }

        void completionMethod(object state)
        {

            AsyncDataAccessState ad = (AsyncDataAccessState)state;
            AsyncOperation asyncOp = ad.AsyncOp;

            ReadLargeFileCompletedEventArgs a = new ReadLargeFileCompletedEventArgs(ad.FileContent, null, false, ad.TaskID);
          
            lock (taskToker.SyncRoot )
            {
                taskToker.Remove(asyncOp.UserSuppliedState);
            }
            asyncOp.PostOperationCompleted(_complated, a);
        }

        public void  ReadLargeFile(string sFilePath,int iTaskID)
        {
            WorkerEventHander weh = new WorkerEventHander(read);
            AsyncOperation op = AsyncOperationManager.CreateOperation(iTaskID);
            lock (taskToker.SyncRoot )
            {
                if (!taskToker.Contains(iTaskID))
                {
                    taskToker.Add(iTaskID,op);

                    FileInfo fi = new FileInfo(sFilePath);
                    AsyncDataAccessState dast = new AsyncDataAccessState(op,iTaskID, (int)fi.Length, weh, new byte[(int)fi.Length]);
                    #region 采用回调方式的做法
                    weh.BeginInvoke(sFilePath,dast, new AsyncCallback(callback), dast);
                    #endregion
                    #region 不采用回调方式时的做法
                    //weh.BeginInvoke(sFilePath, dast, null, null);
                    #endregion
                }
            }
        
        }
        void callback(IAsyncResult ar)
        {
           
            AsyncDataAccessState state =(AsyncDataAccessState) ar.AsyncState;
            WorkerEventHander weh = state.Worker;
            weh.EndInvoke(ar);
            ReadLargeFileCompletedEventArgs args = new ReadLargeFileCompletedEventArgs(state.FileContent, null, false, state.TaskID);
            _complated(args);
        }
       

        public void CancelAsync(int taskId)
        {
            lock(taskToker.SyncRoot )
            {
                object obj = taskToker[taskId];
                if (obj != null)
                {
                    AsyncOperation asyncOp = obj as AsyncOperation;
                    ReadLargeFileCompletedEventArgs args = new ReadLargeFileCompletedEventArgs(
                        null, null, true, taskId);
                    _complated(args);
                }
            }
        }

        private void read(string sFilepath,object userToken)
        {
            AsyncDataAccessState st = (AsyncDataAccessState)userToken;
            FileStream fs = new FileStream(sFilepath, FileMode.Open, FileAccess.Read, FileShare.Read,0x1000 , true);
            byte[] buffer = new byte[0x1000];
            int res = fs.Read(buffer, 0, 0x1000);
            int cnt=0;
            while ( res> 0)
            {
                cnt +=res ;
                byte[] cf=new byte[res];
                for (int i = 0; i < res; i++)
                    cf[i] = buffer[i];
                //lock (st.FileContent.SyncRoot)
                //{
                    cf.CopyTo(st.FileContent, 0);
                //}
                int pctn = (int)((float)cnt / (float)st.FileLen *100);
          
                ReadLargeFileProgressEventArgs args = new ReadLargeFileProgressEventArgs(st.FileLen, cnt,pctn, st.TaskID,cf);
                //Console.WriteLine("read" + cnt.ToString());
                this._reportProgress(args);//-----------A
                #region 异步发送ChangedEvent,不保证发送的顺序,与A点是互斥的
                //    st.AsyncOp.Post(this._reportProgress, args);
                #endregion
                res = fs.Read(buffer, 0, 0x1000);
            }
            fs.Close();
            #region 不采用回调方式时的做法
            //ReadLargeFileCompletedEventArgs args1 = new ReadLargeFileCompletedEventArgs(st.FileContent, null, false, st.TaskID);
            //_completionMethod(st);
            #endregion

        
         }

        internal class AsyncDataAccessState
        {
            public AsyncOperation AsyncOp;
            public int TaskID;
            public int FileLen;
            public WorkerEventHander Worker;
            public Byte[] FileContent;
            public AsyncDataAccessState(AsyncOperation op, int iTaskID, int iFileLen,WorkerEventHander workerDelete,Byte[] _FileContent)
            {
                FileContent = _FileContent;
                AsyncOp = op;
                TaskID = iTaskID;
                FileLen = iFileLen;
                Worker = workerDelete;
            }
        }
    }
}

----------------Program.cs--------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Threading;
using System.IO;
namespace AsyncIO
{
    class Program
    {
        static DateTime St = DateTime.Now;
        static DateTime En;
        static void Main(string[] args)
        {
            Console.WriteLine(St);
            CPX();
            Console.WriteLine(En);
            TimeSpan sp = En - St;
            Console.WriteLine(sp.Milliseconds);
         
        }
        static void CPX()
        {
            AsyncDataAccess da = new AsyncDataAccess();
            da.ReadCompleted += new ReadLargeFileCompletedEventHander(da_ReadCompleted);
            da.ReadProgressChanged += new ReadLargeFileProgressEventHandler(da_ReadProgressChanged);
            da.ReadLargeFile("H://CC.txt", 10);
            u505A/u5176/u5B83/u7684/u4E8B/u60C5
            Thread.Sleep(100);
        }
      }
 }
       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值