Patterns for delegating work to multiple threads - winforms

I'm updating a WinForms application that uses a BackgroundWorker to do something useful when a button is pressed.
The trouble is, "something useful" iterates sequentially through a long list of things to do, and can take quite a while to complete.
I'm considering having the button press event create multiple BackgroundWorkers instead of one or having the current BackgroundWorker create additional BackgroundWorkers to do the actual work.
Both approaches seem fairly equivalent to me.
Are there advantages/disadvantages to either one? Is there a better way to do this?

Have you looked at using the background worker with Parallel.For? (Parallel.For # msdn)
Managing the multiple workers could be an issue - that's the kind of thing the Parallel extensions do...
PK :-)

Related

Process lots of small tasks and keep the UI responsive

I have a WPF application that needs to do some processing of many small tasks.
These small tasks are all generated at the same time and added to the Dispatcher Queue with a priority of Normal. At the same time a busy indicator is being displayed. The result is that the busy indicator actually freezes despite the work being broken into tasks.
I tried changing the priority of these tasks to be Background to see if that fixed it, but still the busy indicator froze.
I subscribed to the Dispatcher.Hooks.OperationStarted event to see if any render jobs occurred while my tasks were processing but they didn't.
Any ideas what is going on?
Some technical details:
The tasks are actually just messages coming from an Observable sequence, and they are "queued" into the dispatcher by a call to ReactiveUI's ObserveOn(RxApp.MainThreadScheduler) which should be equivalent to ObserveOn(DispatcherScheduler). The work portion of each of these tasks is the code that is subscribing through the ObserveOn call e.g.
IObservable<TaskMessage> incomingTasks;
incomingTasks.ObserveOn(RxApp.MainThreadScheduler).Subscribe(SomeMethodWhichDoesWork);
in this example, incomingTasks would produce maybe 3000+ messages in short succession, the ObserveOn pushes each call to SomeMethodWhichDoesWork onto the Dispatcher queue so that it will be processed later
The basic problem
The reason you are seeing the busy indicator stall is because your SomeMethodWhichDoesWork is taking too long. While it is running, it prevents any other work from occuring on the Dispatcher.
Input and Render priority operations generated to handle animations are lower than Normal, but higher priority than Background operations. However, operations on the Dispatcher are not interrupted by the enqueing of higher priority operations. So a Render operation will have to wait for a running operation, even if it is a Background operation.
Caveat regarding observing on the DispatcherScheduler
ObserveOn(DispatcherScheduler) will push everything through at Normal priority by default. More recent versions of Rx have on overload that allows you to specify a priority.
One point to highlight that's often missed is that items will be queued onto the Dispatcher by the DispatcherScheduler as soon as they arrive NOT one after the other.
So if your 3000 items all turn up fairly close together, you will have 3000 operations at Normal priority backed up on the Dispatcher blocking everything of the same or lower priority until they are done - including Render operations. This is almost certainly what you were seeing - and that means you might still see problems even if you do all but the UI update work on a background thread depending on how heavy your UI updates are.
In addition to this, you should check you aren't running the whole subscription on the UI thread - as Lee says. I usually write my code so that I Subscribe on a background thread rather than use SubscribeOn, although this is perfectly fine too.
Recommendations
Whatever you do, do as much work as possible on a background thread. That point has been done to death on StackOverflow, and elsewhere. Here are some good resources covering this:
MSDN Entry on WPF Threading Model
MSDN Magazine "Build More Responsive Apps With The Dispatcher", by Shaun Wildermuth
If you want to keep the UI responsive in the face of lots of small updates you can either:
Schedule items at a lower priority, which is nice and easy - but not so good if you need a certain priority
Store updates in your own queue and enqueue them and have each operation you run Invoke the next item from your queue as it's last step.
The bigger picture
It's worth stepping back a bit and looking at the bigger picture as well.
If you separately dump 3000 items into the UI in succession, what's that going to do for the user? At best they are going to be running a monitor with a refresh rate of 100Hz, probably lower. I find that frame rates of 10 per second are more than adequate for most purposes.
Not only that, human beings supposedly can't handle more than 5-9 bits of information in one go - so you might find better ways of aggregating and displaying information than updating so many things at once. For example, make use of master/detail views rather than showing everything on screen at once etc. etc.
Another option is to review how much work your UI update is causing. Some controls (I'm looking at you XamDataGrid) can have very lengthy measure/arrange layout operations. Can you simplify your animations? Use a simpler Visual tree? Think about the popular busy spinner that looks like circling dots - but really it's just changing their color. A great effect that is fairly cheap to achieve. It's worth profiling your application to see where time is going.
I would think about the overrall approach front-to-back as well. If you are reasonably certain you are going to get that many items to update at once, why not buffer them up and manage them in chunks? That would might have advantages all the way back to the source - which perhaps is on a server somewhere? In any case, Rx has some nice operators, like Buffer that can turn a stream of individual items into a larger lists - and it has overloads that can buffer by time and size together.
Have you tried using .SubscribeOn(TaskPoolScheduler.TaskPool) to subscribe on a different thread?
#Pedro Pombeiro has the right answer.
The reason you are seeing the freezes on the UI is that you are queueing the work on the Dispatcher. This means the work will be done on the UI thread. You can think of the Dispatcher as a message pump that is constant draining messages from each of its queues (which you can think of each of the priorities [SystemIdle, ApplicationIdle, ContextIdle, Background, Input, Loaded, Render, DataBind, Normal, Send])
Putting you work onto a different priority queue, does not make it run concurrently, just asynchronously.
To run your work on another thread using Rx, then use SubscribeOn as above. Remember to then schedule any updates to the UI back on to the Dispatcher with ObserveOn.

Silverlight UI Thread Blocking

Can someone please tell me how the processing in Silverlight processes between the UI Thread and the other "worker" threads.
I have a scenario where I have to update several hundred complex UI objects in the view via a viewmodel. Each item is backed by its own viewmodel.
If each viewmodel had a property, for example, called IsSelected, which changed a background color through behaviours, how should I go about making changes to minimal UI Thread blocking?
If I update my (several hundred) viewmodels, it blocks the UI thread for around 4 seconds. How can I determine what's doing the blocking? Are there more efficient ways to update?
Thanks
There are definitely more efficient ways than doing it in one go.
A non-Silverlight specific solution would be to space these updates a few milliseconds apart with DispatcherTimer delayed calls, so the thread has some "breathing space" to carry on with the execution path.
But you should also give some thought to your architecture, if you're dealing with hundreds of VMs it might worth using lazy loading and updating your screen sequentially, in order of importance for your audience.
See this answer too for more explanation: https://stackoverflow.com/a/1710868/21217

Adding controls to winform while allowing user to enter input

I have a WinForms data entry form that will have upwards of 1500 questions. I have the questions broken into sections, and each section will have an unkown number of questions. Each section is its own user control and has rows (2 panels, 2 labels, a textbox, and another user control) created and added dynamically for each question. The section controls are then added to the form.
My problem is that the process takes a lot of time, even with using TPL (Task Parallel Library). I would ultimately like to create/add the controls and allow the user to start entering data at the same time. The controls are going into a scrollable panel. While the user is entering data, that data will need processed on a local database...so more threading could be necessary.
I have tried working with TPL, which I am new to, by having all the controls added to a list during processing and then sorted and added to the form after the Parallel.ForEach was complete...takes about 20 seconds for over 1200 questions.
I also tried utilizing a BackgroundWorker component. Using the BWC seems to be the faster of the two, but there is a race condition for the ProgressChanged() eventhandler and not all controls get added...not to mention the way the form looks with all the rerendering.
Am i just using TPL wrong? What's the best way to go about this? Is there another way or do I just make the user stick out the wait?
Thanks
Am i just using TPL wrong? What's the best way to go about this? Is there another way or do I just make the user stick out the wait?
Most likely, you can use TPL, and get the same response time as BW, but a nicer API for this type of operation.
The trick here is to get a TaskScheduler setup for UI interaction, and then use the Task class to push the controls back onto the UI thread as they're ready. I have a blog post on this specific subject which shows how to get a TaskScheduler setup to use with UI threads.
However, I would recommend keeping these in memory and pushing them in batches, to avoid constantly re-rendering the UI. This is likely to be an issue no matter what you're doing.
That being said - I'd question your overall visual design here - if you're trying to display over 1200 questions to the user, some form of paging is probably a much nicer approach than a huge scrollable container. If you page these, you could load and process the first few (which is probably near instantaneous, since you mentioned you can process about 50 questions/second), and then continue loading the others after the first few questions have been displayed.

WPF performance problem with CommandManager

We've created a new, quite complex, WPF application from the ground up and have run into a performance problem as the number of commands registered with the CommandManager increase. We're using simple lightweight commands in our MVVM implementation, however the third party controls we're using (Infragistics) do not, and call CommandManager.RegisterClassCommandBinding liberally to add RoutedCommands. The performance problem manifests itself as a perceived sluggishness in the UI when responding to user input, for example tabbing between controls is slow, text input is 'jerky' and popup animation is 'clunky'. When the app is first fired up the UI is snappy. As more screens containing Infragistics grids are opened the performance deteriorates.
Internally, the CommandManager has a private field named _requerySuggestedHandlers, which is a List< WeakReference>. I've used reflection to get a reference to this collection, and I've noticed that when I call .Clear(), the responsiveness of the UI improves back to its initial state. Obviously I don't want to go round clearing collections that I know little about, especially using reflection (!) but I did it to see if it would cure the performance problems, and voila it did.
Normally, this situation would clean itself up after a certain amount of time passes. However, the collection of WeakReferences (_requerySuggestedHandlers) will only get trimmed once a garbage collection is initiated, which is non-deterministic. Because of this, when we close down windows containing grids (Infragistics XamDataGrid), the CanExecute property for 'dead' grid commands continue to be evaluated unnecessarily, long after the window is closed. This also means that if we close down a number of windows, the performance is still sluggish until a garbage collect is initiated. I understand that this can happen on allocation, and I've seen that myself because if I open a further window this causes the initial memory (from the disposed Windows) to be collected and performance returns to normal.
So, given the above, here are my questions:
How, and from where, does CommandManager.InvalidateRequerySuggested() get called? I haven't found any documentation on MSDN that explains this in any great detail. I hooked up to the CommandManager.RequerySuggested event and it looks like it's being called whenever controls lose focus.
Is is possible to suppress CommandManager.InvalidateRequerySuggested() being called in response to user input?
Has anyone else run into this issue, and if so, how have you avoided it?
Thanks!
This sounds like one of the rare cases where deterministically calling GC.Collect() is the right thing to do. The ordinary argument against it is that the garbage collector is smarter than you are. But when you're dealing with WeakReference objects, you enter territory where you may know something that the garbage collector doesn't. Kicking off garbage collection is certainly better than clearing _requerySuggestedHandlers - among other things, it won't do anything to the WeakReference objects that point to controls that are still alive.
I'd choose this over trying to figure out how to suppress RequerySuggested, since that would screw up the behavior of those commands that you still care about.

Patterns used in WPF

I have been getting more involved with WPF for about a year now. A lot of things are new and sometimes it is hard to get my head wrapped around it.
At the same time I am rereading the GOF Design Patterns book.
A few times I would stop in the middle because I would realize that a certain pattern is the very one used in some WPF functionality. Whenever such a realization hits me, I feel like my understanding of the related WPF principle just took a big leap. It's kind of like an aha-effect.
I also realized that I had a much easier time understanding Prism for example because the documentation does such a great job at explaining the patterns involved.
So here is my "question" (more like an effort):
In order to help us all to understand
WPF better it would be great if anyone
who also "spotted" a design pattern in
WPF could give a short explanation.
One pretty obvious example that I found is the Routed Event:
If an event is detected by a child
control and no handler has been
specified, it passes it along to its
parent and so on until it is finally
handled or no parent is found anymore.
Lets say we have an image on a button
that is inside a StackPanel that is
inside a window. If the user clicks
the image, the event will either be
handled by it (if handling code has
been specified) or "bubble" up until
one of the controls handles it. So
each control will get a chance to
react in this order.
Image
Button
StackPanel
Window
Once a control handles it, the
bubbling will stop.
This is the short explanation, for a
more precise one consult the WPF
literature.
This kind of functionality represents
the "Chain of Responsibility
Design Pattern" which states, that if
their is a request, it gets passed
along a responsibility chain to give
each object in it a chance to handle
it. The sender of the request has no
idea who will handle it which ensures
decoupling. For a more thorough
explanation follow the link.
The purpose here is merely to show how this (seemingly old 10+ years) idea found its way into our current technology and to offer another way of looking at it.
I think this is enough for a start and hope more parallels will be collected here.
Cheers, Thorsten
I don't think it is specific for WPF but the observer design pattern seems to be the foundation on which all event handling in .Net and WPF is based.
The observer design pattern is described as "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.". In .Net with the += operator you subscribe to such a change in state. Subsequently you unsubscribe with the -= operator.
I'd say CommandBindings are pretty important and fundamental to the way I develop.
WPF Tutorial - Command Bindings and Custom Commands
MSDN Overview

Resources