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; }
}
}