关于异步文件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
因此,想到先从最基本的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
相关文章推荐
- 关于异步文件IO
- 关于异步文件IO
- 关于extjs下载excel文件使用到Ajax异步请求
- 关于IO的同步,异步,阻塞,非阻塞
- 关于IO的同步,异步,阻塞,非阻塞
- 关于js异步上传文件
- labview下关于文件输入输出io口的操作
- 关于IO的同步,异步,阻塞,非阻塞
- 没有Form的情况下,关于AJax异步上传文件处理
- 关于用java io实现文件压缩与解压(不涉及压缩算法)
- java关于(io&nio) 的 文件copy例子
- 标准C函数中关于文件IO的函数详解
- IO的五种模型(关于同步与异步,阻塞与非阻塞)
- java IO 关于创建文件的一个细节、技巧
- Python笔记-IO同步和异步、 读写文件、StringIO和BytesIO
- js无刷新无插件异步上传文件,使用dojo.io.iframe发送form数据包
- JAVA基础知识之网络编程——-关于阻塞IO/非阻塞IO/同步IO/异步IO的一些参考文章
- 关于js异步上传文件
- 关于文件异步上传
- 关于IO的同步、异步、阻塞、非阻塞