C#异步读取文件
eg:首先解释一下什么是异步,异步是主线程可以异步方法调用后不用等到其运行结束后再进行后续工作。
那么主线程怎么知道异步操作结束呢:回调函数。
异步不能直接提高效率,异步不是并行编程。
异步与顺序执行相对。但是异步与多线程或者并行编程的同步没有直接的关系。
以下是异步读取文件的代码,注释中写的很清楚了。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace VeviSoft.Utility.IO
{
/// <summary>
/// 异步读文件
/// </summary>
public class FileTransfer
{
public delegate void ReturnEndEvent(object sender, ReturnEndReadEventargs args);
public FileTransfer()
{
BufferSize = 2048;
}
public Stream InputStream { get; set; }
/// <summary>
/// 每次读取块的大小
/// </summary>
public int BufferSize { get; set; }
/// <summary>
/// 读取完成后的返回,返回结果中包含在ReturnEndReadEventargs中
/// </summary>
public event ReturnEndEvent IsReturnEvent;
protected virtual void OnIsReturnEvent()
{
ReturnEndEvent handler = IsReturnEvent;
if (handler != null)
handler(this, new ReturnEndReadEventargs(true,ReadValue.ToString()));
}
/// <summary>
/// 容纳接收数据的缓存
/// </summary>
private byte[] buffer;
/// <summary>
/// 读取文件的字符串
/// </summary>
public StringBuilder ReadValue;
/// <summary>
/// 通过异步方式读取文件
/// </summary>
/// <param name="fileName">文件全路径</param>
/// <returns>读取内容</returns>
public string ReadFileAsync(string fileName)
{
ReadValue=new StringBuilder();
buffer = new byte[BufferSize];
InputStream=new FileStream(fileName,FileMode.Open,FileAccess.Read,
FileShare.Read,BufferSize,useAsync:true);
InputStream.BeginRead(buffer, 0, buffer.Length, OnCompleteRead, null);
//InputStream.write
return ReadValue.ToString();
}
public void OnCompleteRead(IAsyncResult asyncResult)
{
//异步读取一个快,接收数据
int bytesRead = InputStream.EndRead(asyncResult);
//如果没有任何字节,则流已达文件结尾
if (bytesRead > 0)
{
//暂停以对模拟对数据块的处理
Debug.WriteLine("异步线程:已读取一块内容");
var datastr = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
ReadValue.Append(datastr);
//
Thread.Sleep(TimeSpan.FromMilliseconds(20));
//开始读取下一块
InputStream.BeginRead(buffer, 0, buffer.Length, OnCompleteRead, null);
}
else
{
//操作结束
Debug.WriteLine(" 异步线程:读取文件结束");
OnIsReturnEvent();
}
}
}
public class ReturnEndReadEventargs : EventArgs
{
public ReturnEndReadEventargs(bool isReturn,string value)
{
IsReturn = isReturn;
ReadValue = value;
}
public string ReadValue { get; set; }
public bool IsReturn { get; set; }
}
}