共用方式為


Performing Bulk Modifications To a Databound Collection

On a WinForms project in the past we were working on scalability and performance. One of the things we discovered was that individually invoking items to the UI thread was a bottleneck.

The theory is that the each time one does a BeginInvoke it adds a message to the Message queue. This adds overhead. If you are doing this enough then the overhead is significant.

At the time we coded up a little class to buffer items to be added to a ListBox, and then at a given trigger it would do an Invoke for the entire buffer. The triggers included:

· A given number of items in buffer

· A given amount of time since the last invoke

· An explicit flush (usually called at the end of the process generating the items)

With WPF I’ve wondered if this overhead is still a factor.

So I coded up a component which I call CollectionDispatcher. When instantiated one provides a collection (which has some UI data bound to it), the maximum number of items to buffer and a timeout.

Then lets say you have a background thread pulling items over the network from a DB or some API. Every time it gets a new item it calls EnqueueItem which adds the item to the buffer. At a flush even the buffer is dispatched to the UI thread, and the target collection is updated.

I then coded a simple app to vary the parameters to try out the perf and compare it to individually dispatching each item.

What I found was surprising to me. If the time between items was at all significant then the bulk dispatch didn’t seem to make a total time difference. It is only when the delay between items was very small and the number of items large that there was a significant difference.

In thinking about this what I came up with is:

· If the time to generate the items is significant then it overwhelms any overhead from dispatching

· Dispatcher is more performant than the Win32 message pump

· Multicore helps, since the UI thread can pull items off the queue in parallel with the background thread adding them

I haven’t verified the theory (especially the one about the Dispatcher being more performant), so take it with a grain of salt.

My conclusion is that this CollectionDispatcher probably isn’t worth the complexity in most cases, at least from a performance standpoint. It may help reduce jumpiness in a UI, caused by a steady flow of changes to a collection.

The code from this experiment is attached. Use at your own risk and other standard disclaimers. Right now all it does is add items to a collection, but one could easily extend it to handle moves, removes, etc…

CollectionDispatcher.zip

Comments