【发布时间】:2015-06-28 07:41:36
【问题描述】:
所以我决定在 WPF 中重写我的邮件客户端,因为我认为是时候从 Windows 窗体(我仍然喜欢它)继续前进了,但我遇到了一些问题。
我在我的 Windows 窗体应用程序中使用 BackgroundWorker 来做事,并在 foreach 中使用 worker.ReportProgress(currentProgress);,这让我可以在后台执行操作时更新 UI,这很棒。
但是刚刚开始一个新的WPF项目,发现工具箱里没有BackgroundWorker(用于WPF应用)所以我去网上搜索,发现有些人在使用@987654325时更新UI有问题@ 使用 WPF。所以这让我觉得在 WPF 应用程序中使用 BackgroundWorker 有点笨拙——我不希望这样。
在同一页面上,另一个用户将他们引至 this 页面,告诉他们在 WPF 中使用 Task.Run 而不是 BackgroundWorker。在查看 Task.Run 文档后,我立即看到它是如何有用的,但我确实有一个担忧。我看不到“报告进度”或在完成工作时更新 UI 的方法。我所看到的只是如何运行任务和“await”它;只剩下一个选项 - 在长时间运行的任务完成后更新 UI。
我们如何在 Task.Run/TaskFactory.StartNew 仍在工作时更新 WPF 桌面应用程序的 UI?
【问题讨论】:
-
BackgroundWorker类是在 WPF 的后台线程上更新 UI 的主要方法之一。你看过哪些文章表明它很hacky? -
谢谢@AndrewStephens - 我认为它是hacky的原因是因为1)默认情况下它不在WPF应用程序的工具箱中,2)你必须手动添加worker.SupportsProgress = true; (由于缺少此控件的属性窗格,3)我可以看到其他人说 BackgroundWOrker 无法在不使用委托的情况下从 WorkerCompleted 或 ProgressChanged 事件内部更新 UI(这在 WinForms 中不是必需的) - 这导致我相信 BGWorker 可能不完全受支持或不打算在 WPF 应用程序中使用。
-
它是一个类而不是 UI 控件,所以它不会出现在工具箱中。如果使用 MVVM,您通常会在代码隐藏或视图模型中创建它的实例。在 UI 线程上引发 ProgressChanged 事件,因此不需要委托。我敢肯定 WorkerCompleted 也会这样做,但如果不只是将 UI 更新代码包装在
Dispatcher.Invoke()调用中。您会再次发现这是 WPF 中的一种常用技术,尤其是在从其他线程更新 UI 时。 -
非常感谢@Andrew!
标签: c# .net wpf task-parallel-library