Winforms:避免冻结应用程序

我在“大”文件上做了一些操作(大约4Mb)

我这样做:1。从目录中获取所有文件并将它们放在IList中MyInfoClass具有以下属性:name,extension,fullPath,creationDate,contentPart 2.我执行Linq查询以仅获取某些扩展类型。 3.我循环查询Linq查询结果,每次打开文件,执行一些操作(获取值)并将结果放入MyFileIno.ContentPart。

仅供参考:30个文件,这是一个14秒的操作

这是工作。

问题是,当我从UI运行我的库时,当我单击按钮时,窗口在操作期间冻结。 我想要 :

  1. 解冻不冻结表格
  2. 看进度操作

你能给我解决这类问题的最佳实践吗?

谢谢,

public class FileManager { public string CurrentFileName { get; set; } public void Validation(string path) { IList listFile = GetListFile(path); foreach (InfoFile item in listFile) { CurrentFileName = item.Name; ..... } } } private void button1_Click(object sender, EventArgs e) { var worker = new BackgroundWorker(); worker.DoWork += (s, args) => { int percentProgress = 6; FileManager fileManager = new FileManager(); fileManager.Validation(@"C:....."); ((BackgroundWorker)s).ReportProgress(percentProgress, fileManager.CurrentFileName); }; worker.ProgressChanged += (s, args) => { var currentFilename = (string)args.UserState; label1.Text = currentFilename; progressBar1.Value = args.ProgressPercentage; }; worker.RunWorkerCompleted += (s, args) => { progressBar1.Value = 0; }; worker.RunWorkerAsync(); } 

应用程序冻结,因为您正在主线程中执行文件解析。 您可以使用BackgroundWorker在新线程上执行操作。 这里有一些伪代码可以帮助您入门:

 private void button1_Click(object sender, EventArgs e) { var worker = new BackgroundWorker(); worker.DoWork += (s, args) => { // Here you perform the operation and report progress: int percentProgress = ... string currentFilename = ... ((BackgroundWorker)s).ReportProgress(percentProgress, currentFilename); // Remark: Don't modify the GUI here because this runs on a different thread }; worker.ProgressChanged += (s, args) => { var currentFilename = (string)args.UserState; // TODO: show the current filename somewhere on the UI and update progress progressBar1.Value = args.ProgressPercentage; }; worker.RunWorkerCompleted += (s, args) => { // Remark: This runs when the DoWork method completes or throws an exception // If args.Error != null report to user that something went wrong progressBar1.Value = 0; }; worker.RunWorkerAsync(); }