如果已经更新,如何跳过UI更新?

时间:2011-01-12 16:14:39

标签: c# .net user-interface

[抱歉英语不是我的母语。]

所以,我在另一个线程上有一个UI和一个worker,worker会以随机频率调用UI到Update(), 所以可能会向UI调用很多Update()。但是如果真的有多个Update(),那么只有最新的一个是有意义的,但我无法跳过它们之间的那些。

所以我想

  1. “检测是否有正在进行的更新(),如果是,则再挂一次更新()”

  2. “检查是否还有1个Update()待处理,那么就没有必要等待更多” 在Update()

  3. 之前

    但我不确定最好的方法是什么。我想以前肯定有人遇到过这样的问题。谷歌搜索只是给了我一些无关的结果。所以我正在寻找一些模式或最佳实践或搜索术语或建议或建议。

    非常感谢

3 个答案:

答案 0 :(得分:2)

目前尚不清楚您使用的是哪种类库。但是,调用Update()从根本上说是错误的。绘制UI是一项低优先级的任务,只有在不需要处理任何更重要的事情时才应该这样做。

正确的做法是调用Invalidate()。您可以根据需要多次调用它,它不能“备份”。当UI线程准备好并愿意时,它将绘制用户界面。如果更改发生得更快,那么UI线程可以跟上,那么就不会造成任何伤害,中介涂料就不会发生。

这通常是你需要照顾的其他东西。射击很容易,并且每秒可以调用数百次。这是毫无意义的,人类无法快速感知变化。每秒四十次充足,它看起来像电影中的电影一样流畅。实际上你应该少用。

答案 1 :(得分:1)

好像你需要一个长度为1的更新请求队列。

为队列生成UpdateRequests并在队列已满时丢弃它们......然后从实际执行最终更新调用的另一个线程中将它们消耗到主线程。

答案 2 :(得分:0)

如果您始终希望保证UI线程检索的值是最后一个推送的值,请考虑在UI和后台线程之间共享的数据的堆栈结构。您仍然需要锁定共享数据,以确保UI线程不会“过时”更新。

这是对C#中Stack类的引用:
http://msdn.microsoft.com/en-us/library/system.collections.stack.aspx

根据文件:

  

线程安全
  公共静态(共享   在Visual Basic中)此类型的成员   是线程安全的。任何实例成员   不保证是线程安全的。

     

保证线程安全   堆栈,必须完成所有操作   通过返回的包装器   同步方法。

     

通过集合枚举是   本质上不是线程安全的   程序。即使是收藏品   同步,其他线程仍然可以   修改集合,这会导致   枚举器抛出异常。   确保螺纹安全   枚举,你可以锁定   整个收集   枚举或捕获异常   由其他人做出的改变   线程。

修改
Jorge是对的 - 还有一个Queue类可能更适合:
http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx