在BahamutCMS中的页面生成依靠一个外部程序PGenerator.exe来读取mssql数据库中的发布命令,再生成页面。在这个io操作过程中,先是读取页面模版,将模版调用的文件(图片、js文件、css)先复制到目标的目录中,在通过模版和数据库中的数据生成页面。
可以看到生成页面的操作是比较简单的,一般html文件大小不会超过几百k,关键在复制包含文件的过程中,可能会涉及到很多文件,而且文件可能很大。在PGenerator中,现在使用的是非异步操作方式,因此会造成应用程序短时间内无法响应。
如果使用异步操作,他的一般步骤如下(读取部分):
使用public override IAsyncResult FileStream::BeginRead(
byte[] array,
int offset,
int numBytes,
AsyncCallback userCallback,
object stateObject
);
其中userCallBack为读取操作完成时的回调函数,stateObject是用来传递到回调函数中的一个对象,该对象包含了文件read时的一些信息。我的代码:
public class FileStateObject/////////定义回调函数中传递的对象
{
public byte[] content;///////读取的内容
public FileStream fs;////////操作时的FileStream对象
public int length;/////////////读取的内容长度
}
/////////读取文件
private void OpenFileAnsy()
{
OpenFileDialog ofd=new OpenFileDialog ();
if (ofd.ShowDialog()==DialogResult.OK)
{
string filename=ofd.FileName;
if (File.Exists(filename))
{
FileStream fs=File.OpenRead(filename);
Byte[] content=new byte [fs.Length];
FileStateObject fso=new FileStateObject ();////////为传递给回调函数的对象
fso.content=content;
fso.fs=fs;
fso.length=Convert.ToInt32 (fs.Length);
AsyncCallback readFileCallback = new
AsyncCallback(ReadInFileCallback);/////////定义回调的实例
fs.BeginRead (fso.content,0,fso.length,
readFileCallback,fso);
this.txinfo.Text="start...";
MessageBox.Show ("Read Start");
}
}
}
/// <summary>
/// 当异步完成时的回调操作
/// </summary>
/// <param name="asyncResult"></param>
public static void ReadInFileCallback(IAsyncResult asyncResult)
{
FileStateObject fso=(FileStateObject)asyncResult.AsyncState;////从参数中取出传来的对象
FileStream fs=fso.fs;
int byteread=fs.EndRead (asyncResult);//////结束异步操作
if (byteread==fso.length)
{
MessageBox.Show ("Read Complete");
}
}
这样,当执行到BeginRead()时,系统不在阻塞到文件读取之后,而是直接运行下面的代码。
转: http://blog.thmz.com/user1/9/archives/2005/7.htm