谁能在 WPF 中告诉我,当我们可以通过在 DoWork 事件 Eventhandler 中调用 ReportProgress() 方法来使用 ProgressChangedEvent 事件处理程序更新 UI 时,为什么我们需要使用 Dispatcher.BeginInvoke() 方法从 DoworkEvent 处理程序更新 UI?如果我对后台工作人员和调度员的理解不正确,请纠正我?
2 回答
您需要记住一条规则:
更新 UI 需要从 UI 线程完成。
牢记这一点,让我们看看调度程序做什么以及后台工作人员做什么:
Dispatcher 调度程序是一个对象,当您调用 BeginInvoke 时,它将在创建调度程序的线程上执行方法。应用程序的调度程序始终在 UI 线程上创建,因此这将起作用。
后台工作者
后台工作者非常相似,尽管它提供了一个基于事件的 API:当您ReportProgress
在 DoWork 方法内部调用时,BackgroundWorker 将在创建后台工作者的线程上引发一个事件。因此,如果您在 UI 线程上创建 Background-Worker,您可以在 ProgressChanged 事件处理程序中更新 UI。
您可以从 BackgroundWorker 的 ProgressChanged 处理程序安全地更新 UI,而无需调用 Dispatcher。
每当您调用ReportProgress时,都会引发 ProgressChanged 事件。它在创建 BackgroundWorker 实例的线程上执行,该线程通常是 UI 线程。
从 ReportProgress 的备注部分:
对 ReportProgress 方法的调用是异步的并立即返回。ProgressChanged 事件处理程序在创建 BackgroundWorker 的线程上执行。