指定目錄下存在多個小型文字檔,需以多執行緒方式平行讀取,將所有內容追加至同一個 TextBox 控制項中,不要求順序,僅需換行分隔。
Thread 建立工作執行緒Control.InvokeRequired / Control.Invoke 跨執行緒安全存取 UIFile.ReadAllText 一次性讀取檔案內容using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace MultiThreadFileReader
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSelectFolder_Click(object sender, EventArgs e)
{
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
fbd.Description = "選擇要多執行緒讀取檔案的路徑";
fbd.ShowNewFolderButton = false;
if (fbd.ShowDialog(this) == DialogResult.OK)
{
DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
foreach (FileInfo fi in di.GetFiles("*.txt"))
{
Thread t = new Thread(InvokeThread);
t.Start(fi.FullName);
}
}
}
}
// 委派定義:對應檔案讀取方法簽章
private delegate void ReadFileDelegate(object filePath);
///
/// 執行緒進入點:判斷是否需要跨執行緒叫用
///
private void InvokeThread(object filePath)
{
if (this.InvokeRequired)
{
// 非 UI 執行緒:透過 Invoke 切換至 UI 執行緒
this.Invoke(new ReadFileDelegate(ReadFileContent), filePath);
}
else
{
// 已在 UI 執行緒:直接呼叫
ReadFileContent(filePath);
}
}
///
/// 實際讀取檔案並追加至 TextBox
///
private void ReadFileContent(object filePath)
{
string path = filePath.ToString();
string content = File.ReadAllText(path, Encoding.Default);
this.textBox1.AppendText(content);
this.textBox1.AppendText("\r\n");
}
}
}
| 程式碼片段 | 說明 |
|---|---|
Thread t = new Thread(InvokeThread); t.Start(fi.FullName); | 為每個 .txt 檔案建立獨立執行緒,傳入完整路徑 |
if (this.InvokeRequired) | 檢查目前執行緒是否為 UI 執行緒,避免跨執行緒操作例外 |
this.Invoke(new ReadFileDelegate(ReadFileContent), filePath); | 將檔案讀取工作排程至 UI 執行緒執行 |
File.ReadAllText(path, Encoding.Default) | 一次性讀取整個檔案,適用於小型文字檔 |
textBox1.AppendText(...) | 高效追加文字,自動捲動至末尾 |
ThreadPool.QueueUserWorkItem 或 Task.Run 避免建立過多執行緒SemaphoreSlim 或 Parallel.ForEach 控制同時讀取檔案數File.ReadAllTextAsync 搭配 await 釋放執行緒ReadFileContent 加入 try-catch 避免單一檔案錯誤導致整體失敗原文出處:https://www.zu14.cn/