Advice needed for multi-threading strategy for WPF application - wpf

I'm building a single window WPF application
In the window is a list items (which are persisted in a database of course)
Periodically I need to start a background task that updates the database from an Atom feed. As each new item is added to the database, the list in the UI must also update to reflect this. I don't want this background task to slow down the UI but at the same time it needs to interact with the UI.
Having read loads of articles and seen lots of simple examples, I am still unsure of the best way to implement this.
What I think maybe I could do is:
On the Window_Loaded event, create a DispatchTimer.
When the Tick event fires, call UpdateDb() method.
UpdateDB() will get the items from the Atom feed and add to the database. As I iterate through each item I will call another method to rebind the list to the database so that it "refreshes".
When all the tasks are finished reset the DispatchTimer ??? (not sure if this can / needs to be / done).
Remember, this is background task so a user could be using the UI at the same time.
How does this sound?
Thanks.

This sounds suboptimal because you're doing database connectivity on the UI thread. When the Tick event fires on the DispatcherTimer, handlers will execute on the UI thread. You need to minimize the amount of work you do on this thread to keep the UI responsive, and you definitely shouldn't be doing IO-bound work on this thread.
I would probably have a data service whose responsibility is to update the database and raise events as changes are made. Your UI layer can attach to these events and marshal to the UI thread to apply changes. To marshal to the UI thread, you just need to call Dispatcher.Invoke.
Regardless of your specific approach, the key is to do as much as you can (including any database access) on a separate thread. Marshal back to the UI thread as late as possible and do as little work as possible on the UI thread.
One other thing to note is that WPF automatically marshals changes to scalar values for you. You only need to marshal changes to collections (adding/removing/replacing items).

Your approach would work.
You'd start the timer when the app loads. For each tick of the timer, you start a thread to update the database. Once the database update has happened, you can call .BeginInvoke() on your UI objects to update the UI on the presentation thread (that will be the only time your UI should be affected).

I'd use a System.Threading.Timer, which will call a specified method at a specified interval on a threadpool thread, so no need to create an additional thread, do your db work with that and marshal back to the ui thread as needed.

WPF Multithreading with BackgroundWorker by Pavan Podila:
The good news is that you really don’t have to write such a component since one is available already: the BackgroundWorker class introduced in .Net Framework 2.0. Programmers who are familiar with WinForms 2.0 may have already used this component. But BackgroundWorker works equally well with WPF because it is completely agnostic to the threading model.

Related

windows forms - form freezes when a time-consuming operation takes place

I'm kind of new to Windows Forms. The Windows Forms app I've created is the front-end to a component that does very time-consuming data transformation tasks. The data transformation task emits events which the form subscribes to.
When the form receives an event, it alters the text in a label and calls Refresh() for that label.
When I run the process from the form, it remains responsive and updates the label text for maybe a minute or so. After that, it simply freezes and Windows declares the process 'Unresponsive' until the data transformation is finished, at which time the form unfreezes and the label shows that the data transformation is complete (as expected).
I haven't put the data transformation onto a separate thread - is this the first thing I should try? Can events cross threads? If not, what else should I do?
Yes, threading is where you should be working. Multi threading in WinForms, depending on your version, can be tricky.
If you're using .NET 4.0 or higher, you could be using the Microsoft Task Parallel Library.
Otherwise, there is a good article, here, from C# Corner that covers threading in WinForms applications that I'd suggest as a starting point.
The BackgroundWorker is another option for simplifying threading in WinForms.

Handling multiple threads that need UI access

We have an application that is essentially implementing its own messaging queue. When a user interacts with the application it will generate an action, being a custom action and not the .NET class, that will be handled by our ActionDispatcher.
In the ActionDispatcher class I have a Stack of CustomAction objects. I'd like to run the ActionDispatcher in its own thread, but then you have all the issues with communicating with the main UI thread using Invoke and BeginInvoke.
There are several different methods that the ActionDispatcher may call, each one would require a delegate on the UI side to be used to communicate with the other thread I believe. Is there a simplier way?
The reason for wanting a seperate thread is that the ActionDispatcher processes messages that originate from a server as well as the UI. This is a client application, and many actions are generated by the server. The idea is that I have we have our own queue that both the UI and server add messages to.
It really depends on the architecture of your application, but the quick and short answer is: No. If you're not on the UI thread, then you have to use the Dispather's Invoke or BeginInvoke method to get access or execute code back on the UI thread.
As a side note, this is a little different than in WinForms, it almost sounds like you're coming from a WinForms perspective, so you might want to look up the WPF Dispatcher.
On the other hand, I would suggest that you look into something like Prism's IEventAggregator. I'm sure there are other similar implementations, but Prism has one nice feature, you can tell it you want to subscribe to an event and have it come in on the UI thread and prism does the rest of the work for you.
Personally, I think using an EventAggregator pattern is better, I'm not sure it's necessarily simpler though.
You need to use Dispatcher.CheckAccess().
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.checkaccess.aspx

Create animation on non UI thread

I am having a bit of a problem with a WPF application. The application loads from a database and then creates a bunch of own made Usercontrols. When I load lets say 1000 of these Usercontrols the UI thread blocks. Now I have tried multiple things with loading the Usercontrols on a different thread and then adding them to the main thread, but that is simply not possible I found out (or somebody must have a proper working example).
Is it possible to create a thread with a loading animation that is not blocking while the main UI thread is doing things?
Perform most of work in the thread that loads data from database and use Dispatcher class
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx
to perform the UI related operations on the main thread.

Winforms database connection in form_load

I'm not posting any code here, because the question is more general. So I need to populate datagrid with values by calling table adapter's methods (2 tier app). Usually I do that in form load event. Since recently though, database server becomes unavailable which results in a hanging form. That's nasty.
Could you share some common scenarios you use to avoid that?
May be I should rather do that in Shown event? And yet better do it asynchronously, say with a backgroundworker?
I do in this way:
- I disable datagrids and show some message in a StatusBar
- In Shown event I start a BackgroundWorker that loads from db and fills datasets
- When worker completes its job I enable datagrids...
In this way your form can handle user inputs without hanging or having refresh problems...

How to increase the performance of WPF Application

I have developed WPF Application. In that application iam loading 200mb photos to the listbox.After that Iam adding those images to canvas.While adding photos to canvas after sometime (i.e; after adding 10mb images)iam getting Some error like ----
*****The CLR has been unable to transition from COM context 0x10b46f0 to COM context 0x10b4860 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.*****
Is there any way to increase the performance of my application. I need a solution for this problem.
Any Suggestions for this.
Don't load all 200 mb of photos into the listbox all at once on your UI thread. Will the user be looking at 200 mb all at once? It'll take some work on your part, but you're going to need to do some delayed loading of the images from a background thread.
Take a look at this article (Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps), it may help.
This looks like two questions, the first is that you are loading images in a background thread, but not doing it correctly; thus, the COM error. Double check that you are have a STAThread application and that the image loading thread is not interacting with the WPF dispatch thread incorrectly. Here's a discussion MTA vs. STA; however, WPF needs STA, and it's a loosing battle to fight it.
The second question seems to be how should one do this; that is, loading a bunch of images for display. I would look into using a lazy data binding of the ListView and let the virtualizing presenter that's built into is manage the loading/display of the images.
Here's some docs on using a view-model. The viewmodel could coordinate the image load and provide the ListView with a binding source that would automatically get the application working.
A simpler alternative might be to start up a background thread and load the images into an ObservableCollection<>, bind that to the ListView and let the framework deal with the display.
I second what Greg D said, loading 200mb of images sounds like a recipe for problems.

Resources