[英]How to add events to C# windows application with long processing step
我有一個 Windows 窗體應用程序,它的主要任務是讀取大文本文件中的每一行,然后在該行上執行一些搜索和替換后將該行寫入另一個文件。 由於文件非常大,超過 20 GB,該過程預計需要很長時間才能完成。
讀取、修改、寫入大文本文件的每一行的過程都會很耗時,所以我想在此過程中通知用戶應用程序的進度。 無非是計算文件中的行數,然后將當前行數除以完成工作的百分比。
我知道這是事件和委托的用武之地,但我不得不承認,即使在閱讀了許多關於如何使用這種模式的文章之后,我仍然感到困惑。 向我展示如何向此應用程序添加事件的任何幫助都會有所幫助。
下面是我正在嘗試做的一個例子。 必須用文件中的x
替換t
所有值。
WinForm 類
namespace ParseFileTool
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void btnStartProcessing_Click(object sender, EventArgs e)
{
ProcessFile pf = new ProcessFile();
pf.InputFilePath = "PATH TO INPUT FILE";
pf.OutputFilePath = "PATH TO OUTPUT FILE";
pf.StartProcessing();
}
}
}
文件處理器類
class ProcessFile
{
public string InputFilePath { get; set; }
public string OutputFilePath { get; set; }
public void StartProcessing()
{
using (StreamReader sr = new StreamReader(this.InputFilePath))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string newLine = line.Replace("t","x");
using (FileStream fs = new FileStream(this.OutputFilePath, FileMode.Append, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(newLine);
}
}
}
}
}
我還想知道是否應該在單獨的線程上啟動ProcessFile
類的實例,以允許 GUI 正確更新,或者這不是必需的,因為要使用事件。
感謝您的幫助。 我肯定希望對事件感到滿意並訂閱它們。 我了解什么是委托,但我仍然不確定在哪里聲明它(winform 類或ProcessFile
類)以及如何處理傳遞回事件處理程序的數據(如處理的行號)。
我喜歡WinForms
的BackgroundWorker
,盡管您也可以研究更新的async/await
模型。
將BackgroundWorker
拖放到FormMain
表單上並設置ReportsProgress = true
。 訂閱可用事件,用於工作和報告進度。
將任何不接觸 UI 的內容移動到DoWork
事件中,該事件在單獨的線程上運行。 修改您的循環,使其定期報告進度。
public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var inputFilePath = "input file path";
var outputFilePath = "output file Path";
using (var sr = new StreamReader(inputFilePath))
{
int counter = 0;
string line;
while ((line = sr.ReadLine()) != null)
{
// do all the important stuff
counter++;
// report progress after every 100 lines
// reporting too often can essentially lock the UI by continuously updating it
if (counter % 100 == 0)
backgroundWorker1.ReportProgress(counter);
}
}
}
ProgressChanged
事件在 UI 線程上運行,因此您可以接受傳遞給它的任何DoWork
事件並將其顯示給用戶。
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
lblProgress.Text = string.Format("Processed {0} lines.", e.ProgressPercentage);
}
您可能也想訂閱RunWorkerCompleted
事件...
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lblProgress.Text = "Job finished!";
}
通過調用啟動它:
backgroundWorker1.RunWorkerAsync();
您需要使用后台線程。 這里有很多選項,但最簡單的是:
Task.Run(() => pf.StartProcessing());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.