在C#中,我有几个工作,我需要将其反映到UI中。更新进度条,将项目添加到列表等等。
我第一次尝试这样做时,我使用锁来准备一切,以确保每个给定时刻只有一个线程访问UI但我得到了一个例外。所以我了解到我需要使用Dispatcher.Invoke
来访问和更改UI元素。将每个UI更改封装到调用中非常麻烦,但我可以处理它。
Dispatcher.Invoke
次来电或内部完成?所以我想知道是否需要添加另一层带锁的保护...... 答案 0 :(得分:7)
人脑无法处理200次更新/秒。它只会减慢你的用户界面,而不会让你获得任何东西。
相反,制作一个定时器,每个轮询状态,比如200ms。这将足够快(5次更新/秒),不会引人注意。
无需锁定调度程序,它在内部处理。但是你应该将你的任务专门用于计算,而不是从他们那里操纵UI。像我说的那样实现一个计时器,并使用一些标准的跨线程通信方式从UI线程中检索当前状态。
答案 1 :(得分:3)
是否有必要同步Dispatcher.Invoke调用或内部完成?所以我想知道我是否需要用锁添加另一层保护......
不,这是多余的。
是否会影响排队到调度员的许多更新请求的性能?因此,如果多个线程工作并且每个线程都通过一个小的更改反映到UI中,那么对Dispatcher.Invoke`发出许多调用会如何影响性能?我应该使用计时器并且每秒只更新一次UI并在内部对所有UI更改进行排队吗?
如果你使用Invoke
而不是BeginInvoke
,你就不会填满队列(除非你有太多的线程),每个线程都会等待它的动作由调度员。
垃圾邮件调度程序可能会影响性能。您不需要经常更新UI。如果你经常等待调度员,你只会浪费时间而失去多线程的好处。
更好的选择是调用BeginInvoke
并不经常这样做以避免压倒主线程。这样,在等待UI更新时,您不会浪费处理线程的时间。
是否有一种更简单的方法来进行跨线程访问更多内联...没有Invokes?
如果您可以将工作人员代码内联,则async / await:
UpdateUI();
await Task.Run(...);
UpdateUI();
如果您使用Paraller.ForEach
,则可以将进度值放入可变,原子递增的位置,并使用计时器更新UI。