【问题标题】:How To Process Many Files Quickly In C# Desktop App Without Freezing App如何在 C# 桌面应用程序中快速处理许多文件而不冻结应用程序
【发布时间】:2019-05-17 23:15:22
【问题描述】:

我在可移动媒体设备上有大约 500 张 JPEG 图像。我的桌面应用程序 (.NET 4.5) 是一种 Winforms 表单,当前使用 Directory.EnumerateFiles 在列表中包含这些图像的 FileInfo 对象。那里没问题,而且很快。主要目的是获取所有这些文件并将它们上传到 S3 存储桶,同时还通过 REST API 调用进行一些日志记录,并向用户报告所有文件的进度,当然当整个文件集完成时正在上传。

如何获取这个 FileInfo 对象列表并最有效地处理它们,同时更新进度条并允许用户在不冻结的情况下移动表单?在一个简单的 ForEach 循环中做事显然很慢。处理每个文件涉及将图像上传到 S3 存储桶(如果存在某些元数据字段),写入 REST API 以将记录存储在 SQL 数据库中,然后更新 UI 以通知用户进度以及在视觉文件中标记文件数据网格为“完成”。我可以很好地完成所有代码,但不确定如何同时浏览此文件列表,同时不会导致表单出现 UI 问题。

我真正的问题:我听到很多人提到 Parallel.ForEach、TPL、使用 Tasks、Async/Await,我正在努力理解哪个是我的用例的最佳选择,以及如何去更新UI/进度条没有问题。

【问题讨论】:

标签: c# .net async-await task-parallel-library parallel.foreach


【解决方案1】:

因为这是一个IO 绑定的工作负载,并且您的库可能支持async,所以async 和await 模式 是要走的路。这将允许在 OS 处理 IO 完成端口 时有效使用 线程池线程,这意味着在将工作卸载到 IO 绑定操作时线程池Pattern 还可以管理 continuations 和 同步上下文,以便您可以更新 UI

由于Parallel.For/ForEach 不支持异步等待模式 并且最终效率低下,因此最简单的方法是Task.Run 和Task.WhenAll 与async 方法。

不过,我还想看看 Microsoft TPL DataFlow 库中的 ActionBlock<T> 这将为您提供能够使用 async 和 await 模式的两全其美,同时也限制了最大并行度。

另一个选择是响应式扩展,它也有所有这些好东西

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多