1

我正在使用 .NET 4.5 在 WPF 中编写应用程序。该应用程序允许用户选择多个文件并导入它们。发生这种情况时,应用程序将解析文本文件并将数据存储到数据库中。这些文件可能非常大,所以我希望 UI 保持响应并允许用户在发生这种情况时做其他事情。

我是异步编程的新手,想知道最好的方法是什么?根据微软的一篇文章...

“async 和 await 关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不在其自己的线程上运行。该方法在当前同步上下文上运行并使用线程上的时间仅当该方法处于活动状态时。您可以使用 Task.Run 将 CPU 绑定的工作移至后台线程,但后台线程无助于等待结果可用的进程。

由于我正在处理多个文件,我会更好地为每个文件使用“Task.Run”,因为它们将在单独的线程上运行?如果不是,使用 async/await 在同一个线程上运行所有内容有什么好处?

请注意,没有其他 UI 操作(进度条 - 进度报告除外)真正关心这些文件何时完成处理,因此根据本文,使用 Task.Run 似乎对我有益。你怎么认为?

4

1 回答 1

3

你用这些文件做什么?如果您正在做任何 CPU 密集型操作,最好将该处理移出 UI 线程。如果它真的只是 IO,那么您可以在 UI 线程中完成这一切 - 并且仍然使其并行。

例如:

private async Task ProcessAllFiles(IEnumerable<string> files)
{
    List<Task> tasks = files.Select(x => ProcessFile(x))
                            .ToList();
    await Task.WhenAll(tasks);
    textBox.Text = "Finished!";
}

private async Task ProcessFile(string file)
{
    // Do stuff here with async IO, and update the UI if you want to...
}

在这里,您仍然在 UI 线程上进行所有实际处理 - 除了潜在的 IO 完成端口之外,没有单独的线程正在运行 - 但您仍然同时启动多个异步 IO 操作。

现在要考虑的另一件事是,这实际上可能会减慢一切。如果您在同一个物理磁盘上处理多个文件,您可能会发现,由于磁盘 IO 的性质,按顺序访问它们会更快。不过,这取决于磁盘类型(例如,SSD 与“常规”磁盘的行为不同)。

于 2013-03-02T23:02:20.887 回答