【发布时间】:2017-10-25 22:19:57
【问题描述】:
我的代码应该工作(据我的最佳理解),但它没有。
我有一个 Windows 窗体应用程序。它有一个扫描选定目录的按钮,这可能会导致找到大量文件。扫描约 50k 文件时,大约需要 10 秒。
我尝试实现异步,以与主 GUI 异步运行文件扫描本身,但这会造成麻烦。任务本身运行良好,但仍会阻塞 GUI,导致整个应用程序冻结。
这是我的按钮代码
private async void BeginScanButton_Click(object sender, EventArgs e)
{
if (_osuDirectory == null)
MessageBox.Show("You have not chosen an Osu! directory yet.");
else
{
await ScanFilesTask();
}
还有很多,但这是其中的相关部分。
任务本身是
private Task ScanFilesTask()
{
FileList.Clear();
return Task.Run(() =>
{
if (_jpgFilesChecked)
FileParser.ParseFiles(_osuDirectory, "*.jpg");
if (_pngFilesChecked)
FileParser.ParseFiles(_osuDirectory, "*.png");
if (_wavFilesChecked)
FileParser.ParseFiles(_osuDirectory, "*.wav");
if (_aviFilesChecked)
FileParser.ParseFiles(_osuDirectory, ".avi");
});
}
最后,FileParser 类只是
public static void ParseFiles(string dir, string extension)
{
Form1.FileList.AddRange(Directory.GetFiles(dir, extension, SearchOption.AllDirectories));
}
(如果有人想看,所有代码都在github repo 上。相关的异步代码在 AsyncTest 分支中。)
这里的任何帮助将不胜感激。这是我的第一个真正的 C# 项目,非常感谢任何正确方向的指针。提前致谢!
【问题讨论】:
-
我很惊讶这甚至可以工作。您正在从位于不同线程上的
Task.Run()执行Form1.FileList.AddRange。所以我假设你正在线程死锁你自己的应用程序。什么是文件列表? -
FileList 是一个静态列表
。它是静态的,所以我可以从 FileParser.cs 中添加它(我意识到这可能是一种完全愚蠢的做法,但我不知道如何去改变它。) -
在这种情况下,因为您正在
await(字面意思是等待)等待ScanFilesTask()完成,所以它阻塞了 UI 线程。 -
谢谢!它现在正在工作 - 我将文件解析逻辑移到了任务中,它按预期运行。我真的很感激!
-
不完全!我正在用最佳做法回答你的问题。
标签: c# .net winforms asynchronous