您的位置:首页 > 其它

关于异步文件IO

2007-06-01 12:45 295 查看
近来由于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);
}
}
}

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1632808
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: