2012-10-05

[C#] 一個簡單案例透過await 讀取大量檔案

 

不知不覺的 10 年了,Anders Hejlsberg 發明這 C# 語言應該也有十年了 …

這幾次改版 C# 加入了 functional programming 的感覺,還有   LINQ 以及 dynamic

這語言真的是越來越精采了,可以玩的東西就很多 …

最近看了一下新的規格,多了一個東西將叫做 await

剛好就用他來處理了讀取大量檔案,順便測試 / 筆記一下 (非教學文)…

// 將傳入目錄全部檔案讀取出來 之後將內容回傳為 string[]
public string[] ReadAllFileContentAndSplitByReturn(string path)
{
    DirectoryInfo di = new DirectoryInfo(path);
 
    return di.GetFiles().Select(file => File.ReadAllText(file.FullName)).ToArray();
 
}
 
// 此處需加上 async
private async void button3_Click(object sender, EventArgs e)
{
 
    // 控制按下後的 UI 處理
    this.button3.Text = " 取資料中 ";
    this.button3.Enabled = false;
 
 
    // 建立一 Task 呼叫
    var readHugeFilesTask = Task<string[]>.Factory.StartNew(() => ReadAllFileContentAndSplitByReturn(@"C:\Users\當麻\Desktop\雜七雜八\Backup_150\"));
 
    await readHugeFilesTask;
    
    
    // 以下為 結束後的處理事件
    this.button3.Text = " 讀取資料";
    this.textBox1.Text = string.Join(Environment.NewLine, readHugeFilesTask.Result);
    this.button1.Enabled = true;
 
    MessageBox.Show(" 已讀取 " + readHugeFilesTask.Result.Length);
 
}

 


簡單看一下 MSIL Code 他做了啥處理..



private async void button3_Click(object sender, EventArgs e)
{
    bool <>t__doFinallyBodies = true;
    this.button3.Text = " 取資料中 ";
    this.button3.Enabled = false;
    Task<string[]> readHugeFilesTask = Task<string[]>.Factory.StartNew(() => this.ReadAllFileContentAndSplitByReturn(@"C:\Users\當麻\Desktop\雜七雜八\Backup_150\"));
    TaskAwaiter<string[]> CS$0$0001 = readHugeFilesTask.GetAwaiter();
    if (!CS$0$0001.IsCompleted)
    {
        this.<>u__$awaiter13 = CS$0$0001;
        AsyncVoidMethodBuilder.Create().AwaitUnsafeOnCompleted<TaskAwaiter<string[]>, <button3_Click>d__11>(ref CS$0$0001, ref (<button3_Click>d__11) ref this);
        <>t__doFinallyBodies = false;
        return;
        CS$0$0001 = this.<>u__$awaiter13;
    }
    CS$0$0001.GetResult();
    CS$0$0001 = new TaskAwaiter<string[]>();
    this.button3.Text = " 讀取資料";
    this.textBox1.Text = string.Join(Environment.NewLine, readHugeFilesTask.Result);
    this.button1.Enabled = true;
    MessageBox.Show(" 已讀取 " + readHugeFilesTask.Result.Length);
}
 
 

 


其中我們可以看到他封裝了 TaskAwaiter 結構 ,果然讓我們省事很多..


讓新的寫法看起來,非常的舒服,而且符合編程邏輯


網路上我有找到一篇文章很有參考價值 …


http://msdn.microsoft.com/zh-tw/magazine/hh456403.aspx


其中講解得非常詳細.. 這邊就不贅述 …


最後我們在驚呼  Anders Hejlsberg  真的是神


 


參考文件:


http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx


http://msdn.microsoft.com/en-us/library/hh156528(v=vs.110).aspx