How to skip UI update if already updating?
[Sorry that English is not my native language.]
So, I have a UI and 1 worker on another thread, the worker will call the UI to Update() in random frequency, so there might be a lot of Update() invoked to the UI. But if there are really multple Update(), then only the latest one is meaningful, yet I have no way to skip those in between.
So I want to
"detect if there is an Update() ongoing, if yes, just pend 1 more Update()"
"check if there is already 1 more Update() pending, then there is no need to pend more" before the Update()
But I am not sure what's the best way to do it. I think surely someone has encountered such problem before. Googling just gives me some unrelated result. So I am looking for some patterns or best practices or search terms or advice or suggestion about this.
开发者_开发百科Thank you very much
It isn't clear what kind of class library you are using. However, invoking Update() is fundamentally wrong. Painting the UI is a low priority task, it should only be done when nothing more important needs to be taken care of.
The proper thing to do is call Invalidate(). You can call it as many times as you want, it cannot 'backup'. When the UI thread is ready and willing, then it will paint the user interface. If the changes happen faster then the UI thread can keep up with then no harm is done, the intermediary paint just didn't happen.
Which is in general something else you need to take care of. It is pretty easy to shoot the foot and invoke hundreds of times per second. Which is pointless, a human cannot perceive changes that fast. Forty times per second is plenty, it looks as smooth as a movie in cinema. Realistically you should use less.
Seems like you need a queue of Update requests with a length of one.
Produce UpdateRequests to the queue and discard them if the queue is full... then consume them from another thread that actually does the final update invoke to the main thread.
If you always want to guarantee that the value retrieved by the UI thread is the last one pushed, consider a stack structure for the data you're sharing between the UI and background threads. You will still need to put a lock on the shared data to ensure that the UI thread doesn't get a "stale" update.
Here's a reference to the Stack
class in C#:
http://msdn.microsoft.com/en-us/library/system.collections.stack.aspx
According to the documentation:
Thread Safety
Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.To guarantee the thread safety of the Stack, all operations must be done through the wrapper returned by the Synchronized method.
Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
EDIT:
Jorge is right- there is also a Queue
class that might be better suited:
http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx
精彩评论