在 UI 线程上运行昂贵的操作时保持 UI 视觉更新
在我的 WPF 应用程序中,我需要在 UI 线程上运行一个昂贵的操作(我们称之为 ExpenseUIOperation()
),并且我希望使 UI 保持最新状态以跟踪其进度。
为了跟踪进度,我只需使用一个 TextBlock
,其 Text
属性绑定到整数依赖属性 PercentageComplete
。在 ExpenseUIOperation()
期间,我只需根据需要设置 PercentageComplete
的值。
现在,我对线程有了足够的了解,知道如果我只是在 UI 线程上运行 ExpenseUIOperation(),TextBlock 就不会出现保持最新状态,因为UI 线程将被阻塞,从而停止任何界面更新。
所以我想我可以像这样异步执行:
Dispatcher.BeginInvoke(new Action(ExpensiveUIOperation), DispatcherPriority.Background);
但这仍然不起作用。在操作完成之前,文本块不会在视觉上更新。
有办法做到这一点吗?
不幸的是,在这种情况下我无法使用后台线程,因为该操作大量使用了 UI 线程拥有的对象。
In my WPF app, I need to run an expensive operation on my UI thread (let's call it ExpensiveUIOperation()
), and I want to keep the UI up to date to track it's progress.
To track progress, I simply have a TextBlock
, whose Text
property is bound to an integer dependency property PercentageComplete
. During ExpensiveUIOperation()
, I simply set the value of PercentageComplete
as required.
Now, I understand enough about threading to know that if I simply ran ExpensiveUIOperation()
on my UI thread, that the TextBlock would not appear to keep up to date, as the UI thread would be blocked, stopping any interface updates.
And so I thought I could do it asynchronously like this:
Dispatcher.BeginInvoke(new Action(ExpensiveUIOperation), DispatcherPriority.Background);
But that is still not working. The text block is not visually updated until the operation completes.
Is there a way to do this?
Unfortunately in this situation I cannot use a background thread, as the operation makes heavy use of objects owned by the UI thread.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不是滥用 UI 线程的充分理由。访问这些元素时使用调度程序(请参阅遍历模型参考),或者将您的视图正确绑定到相关属性,您甚至不需要这样做,因为更新会在 UI 内部排队。
That is not a good enough reason to abuse the UI-thread like this. Use the Dispatcher when accessing those elements (see the treading model reference), or properly bind your view to relevant properties and you will not even need to do that as updates are queued to the UI internally.
您被卡住了,UI 操作必须在 UI 线程上进行,并且在发生这种情况时不会发生 UI 更新。您可以通过创建一个新的调度程序框架(http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html)但它是危险,你会在更新过程中捕获 UI,这不是一件好事。
昂贵的 UI 操作真的是 CPU 密集型、仅 UI 操作吗?例如,使用视图模型对象图无法完成任何操作,然后最终绑定到 UI?
You're stuck, UI operations have to occur on the UI thread, and while that occurs no UI updates will happen. You could do the equivalent of an
Application.DoEvents
in WPF by creating a new dispatcher frame (http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html) but it is dangerous, you will catch the UI in the middle of updates and not a good thing to do.Is the expensive UI operation really a CPU-intensive, UI-only operation? Nothing that can be done with a View Model object graph and then finally bound to the UI, for example?