如何在不冻结应用程序的情况下在 C# 桌面应用程序中快速处理多个文件
How To Process Many Files Quickly In C# Desktop App Without Freezing App
我在可移动媒体设备上有大约 500 张 JPEG 图片。我的桌面应用程序 (.NET 4.5) 是一个 Winforms 表单,当前使用 Directory.EnumerateFiles 在列表中包含这些图像的 FileInfo 对象。没问题,而且很快。主要目的是获取所有这些文件并将它们上传到 S3 存储桶,同时还通过 REST API 调用进行一些日志记录,并向用户报告所有文件的进度,当然还有当整个文件集上传完毕。
我如何获取这个 FileInfo 对象列表并最有效地处理它们,同时更新进度条并允许用户在不冻结的情况下移动表单?在一个简单的 ForEach 循环中做事显然很慢。如果某些元数据字段存在,处理每个文件涉及将图像上传到 S3 存储桶,写入 REST API 以将记录存储在 SQL 数据库中,然后更新 UI 以通知进度的用户以及在可视化数据网格中将文件标记为 "done"。我可以很好地完成所有这些代码,但不确定如何在不导致表单出现 UI 问题的情况下同时浏览此文件列表。
我真正的问题:我听到很多人提到 Parallel.ForEach、TPL、使用任务 Async/Await,我正在努力理解哪个是我的用例的最佳选择,以及如何着手更新 UI/progressbar 没有问题。
因为这是一个 IO 绑定工作负载,并且您的库可能支持 async
,所以 async 和 await 模式是要走的路。这将允许有效地使用 thread-pool 线程 而 OS
处理 IO 完成端口 ,这意味着工作是被卸载到 IO 绑定操作 thread-pool 可以重用这个宝贵的资源,而 Pattern 也管理 continuations 和 同步上下文 所以你可以更新 UI
由于 Parallel.For/ForEach
不支持 异步等待模式 并且最终效率低下,最简单的方法是 Task.Run
和 Task.WhenAll
与 async
方法。
但是,我还会看一下 Microsoft TPL DataFlow 库中的 ActionBlock<T>
这将使您两全其美,能够使用async 和 await 模式,并且还限制了最大并行度。
另一种选择是响应式扩展,它也有所有这些好东西
我在可移动媒体设备上有大约 500 张 JPEG 图片。我的桌面应用程序 (.NET 4.5) 是一个 Winforms 表单,当前使用 Directory.EnumerateFiles 在列表中包含这些图像的 FileInfo 对象。没问题,而且很快。主要目的是获取所有这些文件并将它们上传到 S3 存储桶,同时还通过 REST API 调用进行一些日志记录,并向用户报告所有文件的进度,当然还有当整个文件集上传完毕。
我如何获取这个 FileInfo 对象列表并最有效地处理它们,同时更新进度条并允许用户在不冻结的情况下移动表单?在一个简单的 ForEach 循环中做事显然很慢。如果某些元数据字段存在,处理每个文件涉及将图像上传到 S3 存储桶,写入 REST API 以将记录存储在 SQL 数据库中,然后更新 UI 以通知进度的用户以及在可视化数据网格中将文件标记为 "done"。我可以很好地完成所有这些代码,但不确定如何在不导致表单出现 UI 问题的情况下同时浏览此文件列表。
我真正的问题:我听到很多人提到 Parallel.ForEach、TPL、使用任务 Async/Await,我正在努力理解哪个是我的用例的最佳选择,以及如何着手更新 UI/progressbar 没有问题。
因为这是一个 IO 绑定工作负载,并且您的库可能支持 async
,所以 async 和 await 模式是要走的路。这将允许有效地使用 thread-pool 线程 而 OS
处理 IO 完成端口 ,这意味着工作是被卸载到 IO 绑定操作 thread-pool 可以重用这个宝贵的资源,而 Pattern 也管理 continuations 和 同步上下文 所以你可以更新 UI
由于 Parallel.For/ForEach
不支持 异步等待模式 并且最终效率低下,最简单的方法是 Task.Run
和 Task.WhenAll
与 async
方法。
但是,我还会看一下 Microsoft TPL DataFlow 库中的 ActionBlock<T>
这将使您两全其美,能够使用async 和 await 模式,并且还限制了最大并行度。
另一种选择是响应式扩展,它也有所有这些好东西