1. 程式人生 > 實用技巧 >C#非同步檔案讀寫訪問

C#非同步檔案讀寫訪問

可使用非同步功能訪問檔案。通過使用非同步功能,你可以呼叫非同步方法而無需使用回撥,也不需要跨多個方法或 lambda 表示式來拆分程式碼。若要使同步程式碼非同步,只需呼叫非同步方法而非同步方法,並向程式碼中新增幾個關鍵字。

可能出於以下原因向檔案訪問呼叫中新增非同步:

  • 非同步使 UI 應用程式響應速度更快,因為啟動該操作的 UI 執行緒可以執行其他操作。如果 UI 執行緒必須執行耗時較長的程式碼(例如超過 50 毫秒),UI 可能會凍結,直到 I/O 完成,此時 UI 執行緒可以再次處理鍵盤和滑鼠輸入及其他事件。
  • 非同步可減少對執行緒的需要,進而提高 ASP.NET 和其他基於伺服器的應用程式的可伸縮性。如果應用程式對每次響應都使用專用執行緒,同時處理 1000 個請求時,則需要 1000 個執行緒。非同步操作在等待期間通常不需要使用執行緒。非同步操作僅需在結束時短暫使用現有 I/O 完成執行緒。
  • 當前條件下,檔案訪問操作的延遲可能非常低,但以後可能大幅增加。例如,檔案可能會移動到覆蓋全球的伺服器。
  • 使用非同步功能所增加的開銷很小。
  • 非同步任務可以輕鬆地並行執行。
  • 一般來說,非同步的方法命名都是帶有Async字尾的

任何效能提升都幾乎完全來自並行處理而不是非同步處理。 非同步的優點在於它不會佔用多個執行緒,也不會佔用使用者界
面執行緒。

新建.net core 3.1 控制檯應用程式AsyncFileAccessDemo。

注意,在.net framework 4.6尚未存在函式(System.IO.File.AppendAllTextAsync),需使用.net core

一、編寫相應的測試程式:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace AsyncFileAccessDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("準備非同步寫入檔案...");
string path = "F:\\a.txt";

List<Task> tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
Task task = AppendFileAsync(path, Path.GetRandomFileName());
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("這裡已經寫入檔案執行完畢...");
Task<string> taskRead = ReadFileAsync(path);
Console.WriteLine($"讀取的內容:{taskRead.Result}");
Task.WhenAll(taskRead).ContinueWith(p => Console.WriteLine("這裡可以執行其他回撥操作...."));
Console.WriteLine("阻塞任務已完成,啟動其他...");
Console.ReadLine();
}

/// <summary>
/// 向一個檔案中追加內容
/// </summary>
/// <param name="path"></param>
/// <param name="message"></param>
/// <returns></returns>
static async Task AppendFileAsync(string path, string message)
{
await File.AppendAllTextAsync(path, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}->{message}\r\n", Encoding.Default);
}

/// <summary>
/// 讀取檔案的所有內容
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
static async Task<string> ReadFileAsync(string path)
{
string content = await File.ReadAllTextAsync(path, Encoding.Default);
return content;
}
}
}

二、程式執行如圖: