I have a large WPF MVVM application (over 100 windows currently and growing.) Although I try to do everything I can on background threads there always comes a time the results must be sent back to the UI thread to be displayed. When you have many windows doing this at the same time it can effect performance.
I've tried to run each window on a separate UI thread in the past but ran into so many threading issues I had to revert back to WPF's default model of only 1 UI thread per app.
I know with windows 10 coming many users will open even more windows on separate desktops and thus make this worse.
Anyone know how to get multiple UI threads to work correctly in WPF? Or have any info I can investigate to help get my app further down this road?
I approach I tried in the past was to do something similar to this:
private void OnCreateNewWindow(
object sender,
RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
Window1 w = new Window1();
w.Show();
w.Closed += (sender2, e2) =>
w.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
This was about 2 years ago and I can no longer recall all the issues I faced using this unfortunately.
Is there another way? Has anyone gotten an app with many windows to work correctly using this approach or another?
In general, it "works". The main thing you have to do is set the thread to STA (as in your example). But you gain little or nothing by running some of the UI in a different thread. Each thread can still be blocked by long-running tasks, so you still need to execute those in yet another thread, and you still have the cross-thread issue requiring some kind of marshaling back to the UI thread (e.g. Dispatcher.Invoke()).
Furthermore, with more than one UI thread, now not only do you have to keep track of which UI thread goes with which UI object (since they still can be used only with the thread that owns them), you will have more problems with UI objects interacting with each other, because those owned by different threads are mutually exclusive. Each is required to be accessed only in the thread in which it's owned, so the only way to have them work together is to create some kind of proxy system to pass data and events back and forth between threads.
Basically, it never was and still is not a good idea to create more than one thread for the UI.
Fortunately, as of .NET 4.5 and C# 5.0, there are framework and language features that greatly simplify the handling of background operations and the marshaling of information back to the UI thread. With the async/await feature, you can initiate asynchronous operations with framework features like the Task<T> class or certain class methods (usually with names ending in the word Async), have the UI thread unblocked for the duration of the operation, and yet easily write code to handle whatever work has to be done at the end of the operation.
There is also the Progress<T> class, which implements the IProgress<T> interface in a way that is convenient for dealing with UI progress updates, i.e. invokes the callback on the UI thread (as long as you create the Progress<T> instance in the UI thread, of course).
So, take the path that .NET and C# are encouraging you to take, and avoid the one that is hard. Keep all your UI in a single thread, and solve whatever issues come up using the tools provided instead of trying to fight the API. :)
Related
I'm building a WPF application. I'm doing some async communication with the server side, and I use event aggregation with Prism on the client. Both these things results in new threads to be spawned which are not the UI thread. If I attempt to do "WPF operations" on these callback and event handler threads the world will fall apart, which it now has started doing.
First I met problems trying to create some WPF objects in the callback from server. I was told that the thread needed to run in STA mode. Now I'm trying to update some UI data in a Prism event handler, and I'm told that:
The caller cannot access this thread because a different thread owns it.
So; what's the key to getting things right in WPF? I've read up on the WPF Dispatcher in this MSDN post. I'm starting to get it, but I'm no wizard yet.
Is the key to always use Dispatcher.Invoke when I need to run something which I'm not sure will be called on the UI thread?
Does it matter if it actually was called on the UI thread, and I do Dispatcher.Invoke anyway?
Dispatcher.Invoke = synchronously. Dispathcher.BeginInvoke = async?
Will Dispatcher.Invoke request the UI thread, and then stop to wait for it? Is it bad practice and risk of less responsive programs?
How do I get the dispatcher anyway? Will Dispatcher.CurrentDispatcher always give me the dispatcher representing the UI thread?
Will there exist more than one Dispatcher, or is "Dispatcher" basically the same as the UI thread for the application?
And what's the deal with the BackgroundWorker? When do I use this instead? I assume this is always async?
Will everything that runs on the UI thread (by being Invoked) be run in STA apartment mode? I.e. if I have something that requires to be run in STA mode - will Dispatcher.Invoke be sufficient?
Anyone wanna clearify things for me? Any related recommendations, etc? Thanks!
Going over each of your questions, one by one:
Not quite; you should only invoke onto the UI thread when necessary. See #2.
Yes, it does matter. You should not just automatically Invoke everything. The key is to only invoke onto the UI thread if necessary. To do this, you can use the Dispatcher.CheckAccess method.
That is correct.
Also correct, and yes, you do run the risk of less responsive programs. Most of the time, you are not going to be looking at a severe performance hit (we're talking about milliseconds for a context switch), but you should only Invoke if necessary. That being said, at some points it is unavoidable, so no, I would not say it is bad practice at all. It is just one solution to a problem that you will encounter every now and then.
In every case I have seen, I have made due with Dispatcher.CurrentDispatcher. For complex scenarios, this may not be sufficient, but I (personally) have not seen them.
Not entirely correct, but this line of thinking will not do any harm. Let me put it this way: the Dispatcher can be used to gain access to the UI thread for the application. But it is not in and of itself the UI thread.
BackgroundWorker is generally used when you have a time-consuming operation and want to maintain a responsive UI while running that operation in the background. Normally you do not use BackgroundWorker instead of Invoke, rather, you use BackgroundWorker in conjunction with Invoke. That is, if you need to update some UI object in your BackgroundWorker, you can Invoke onto the UI thread, perform the update, and then return to the original operation.
Yes. The UI thread of a WPF application, by definition, must be running in a single-threaded apartment.
There's a lot to be said about BackgroundWorker, I'm sure many questions are already devoted to it, so I won't go into too much depth. If you're curious, check out the MSDN page for BackgroundWorker class.
I am running a C# winform application that shows huge number of statistics and charts frequently. This application consist of multiple forms, each form has different output. When I open the task manager and check out the cpu usage, I find that only one core out of my eight cores is over loaded and the rest are doing nothing!
Is there a way, for example, to assign each number of forms to a core. I need to improve the perfomance.
What I am looking for is to multithread my winforms such that each form would have a different thread that is running on a different core. Is that possible ?
The bottleneck is happening from loading the data into the controls.
It is possible to have multiple UI threads in a single WinForms application. Each UI thread must call Application.Run() and you'd need to mark the entry point to each with [STAThread] just like you do in the Main function.
I have successfully done this and it's a reasonable approach when faced with an existing codebase that's doing too much work on its UI thread. But... I would say this is a symptom of a design that could be improved in other ways. If you're doing too much work on your UI thread think about ways to get that work done on other threads. In my apps I've tried to get all non-trivial work done on non-UI threads. It can be done, but it's not always the fastest way to deliver software.
If doing no other work, a single UI thread is ample to draw 8 screens full of numbers and charts, and update them more frequently than a human can keep up. I know this to be the case :-)
This is technically doable, more flexible in WPF than in WinForms (in my experience), but not recommended in either. Windows client apps tend to run with a single thread responsible for drawing the UI; typically background threads are used for background processing of data access or business logic. Additionally, you'd have to be doing a lot of work in the UI for rendering performance to actually be an issue - this sounds like unnecessary work to me.
However, the basic style in WinForms would be something like this:
var t = new Thread(() =>
{
var f = new Form1();
Application.Run(f);
})
t.Start();
Things you need to be aware of:
you will always have to Invoke calls between forms to make sure they're on the right thread.
if anything in your business layer has thread affinity, you'll need one instance per form that uses it.
application shutdown typically happens in response to the main thread's forms closing. You may need to handle your shutdown manually, though with the code above you have two message loops running and either will keep the app alive when the other's form closes.
Always do data crunching, receiving from I/O, parsing and whatnot on a separate thread or several threads if you need/want.
Then if you're loading a lot of data to UI controls, make sure you don't synchronize with the UI thread too often, like if you invoke every single item from an input stream separately and there are thousands of these per second - WinForms will grind to a halt.
Queue visual data changes in your background thread(s) and batch them to the UI thread with a minimum interval so as to not do this too often - the thread sync is expensive. AddRange is your friend.
So far during my experience in Windows Phone 7 application development I notices there are different ways to runs an action in an asynchronous thread.
System.Threading.Thread
System.ComponentModel.BackgroundWorker
System.Threading.ThreadPool.QueueUserWorkItem()
I couldn't see any tangible difference between these methods (other than that the first two are more traceable).
Is there any thing you guys consider before using any of these methods? Which one would you prefer and why?
The question is kinda answered but the answers are a little short on detail (IMO).
Lets take each in turn.
System.Threading.Thread
All the threads (in the CLR anyway) are ultimately represented by this class. However you probably included this to query when we might want to create an instance ourselves.
The answer is rarely. Ordinarily the day-to-day workhorse for dispatching background tasks is the Threadpool. However there are some circumstances where we would want to create our own thread. Typically such a thread would live for most of the app runtime. It would spend most of its life in blocked on some wait handle. Occasionally we signal this handle and it comes alive to do something important but then it goes back to sleep. We don't use a Threadpool work item for this because we do not countenance the idea that it may queue up behind a large set of outstanding tasks some of which may themselves (perhaps inadverently) be blocked on some other wait.
System.ComponentModel.BackgroundWorker
This is friendly class wrapper around the a ThreadPool work item. This class only to the UI oriented developer who occasionally needs to use a background thread. Its events being dispatched on the UI thread makes it easy to consume.
System.Threading.ThreadPool.QueueUserWorkItem
This the day-to-day workhorse when you have some work you want doing on a background thread. This eliminates the expense of allocating and deallocating individual threads to perform some task. It limits the number of thread instances to prevent too much of the available resources being gobbled up by too many operations try to run in parallel.
The QueueUserWorkItem is my prefered option for invoking background operations.
It arguably depends on what you are trying to do, you have listed 3 very different threading models.
Basic threading
Designed for applications with a seperate UI thread.
Managed thread pool
Have you read MSDN etc...
http://www.albahari.com/threadin
Http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
You don't state "what for", but
Basic Thread - quite expensive, not for small jobs
Backgroundworker - mostly for UI + Progressbar work
ThreadPool - for small independent jobs
I think the TPL is not supported in SL, which is a pity.
The background worker tends to be better to use when your UI needs to be update as your thread progresses because it handles invoking the call back functions (such as the OnProgress callback) on the UI thread rather than the background thread. The other two don't do this work. It is up to you to do it.
I am a beginner with WPF, in my application I need to perform a series of Initialization steps, these take 10-15 seconds to complete during which my UI becomes unresponsive.
I was using yesterday the background worker but it didn't update my window, in fact it was frozen. Not sure, but maybe it didn't work because this control is only for Windows Forms.
UPDATE:
If not too much trouble, can you post me an example to use the alternative? For my case, the program will get some values from a database in a blucle.
Dispatcher.
The Dispatcher maintains a prioritized queue of work items for a specific thread. This might help you for updating your UI. If you have a lot of UI related initializations even this won't be able to help you much.
Dispatcher is not always an alternative to BackgroundWorker actually. The best practice is to select the more appropriate one as per your requirement. For example if you want something to execute without queuing BackgroundWorker is the solution. On the other hand if queuing is not a problem then Dispatcher is an alternative. For example, Dispatcher is using in Spell checkers and syntax highlighting functionality.
WPF Thread Model
All WPF applications start out with two important threads, one for
rendering and one for managing the user interface. The rendering
thread is a hidden thread that runs in the background, so the only
thread that you ordinarily deal with is the UI thread. WPF requires
that most of its objects be tied to the UI thread. This is known as
thread affinity, meaning you can only use a WPF object on the thread
on which it was created. Using it on other threads will cause a
runtime exception to be thrown. Note that the WPF threading model
interoperates well with Win32®-based APIs. This means that WPF can
host or be hosted by any HWND-based API (Windows Forms, Visual Basic®,
MFC, or even Win32).
The thread affinity is handled by the Dispatcher
class, a prioritized message loop for WPF applications. Typically your
WPF projects have a single Dispatcher object (and therefore a single
UI thread) that all user interface work is channeled through.
NOTE :
The main difference between the Dispatcher and other threading methods
is that the Dispatcher is not actually multi-threaded. The Dispatcher
governs the controls, which need a single thread to function properly;
the BeginInvoke method of the Dispatcher queues events for later
execution (depending on priority etc.), but still on the same thread.
See this thread for more information.
You could also queue items up with the thread pool and run the tasks like that, but be careful, if your tasks need to update the UI when they are finished you will have to marshal the data back to the UI thread.
One could use asynchronous delegates.
http://msdn.microsoft.com/en-us/library/ms228963.aspx
Just make sure if you are doing any UI related updates use:
Dispatcher.CheckAccess()
Here a simple example:
private void HandleUIButtons()
{
if (!btnSplit.Dispatcher.CheckAccess())
{
//if here - we are on a different non-UI thread
btnSplit.Dispatcher.BeginInvoke(new Action(HandleUIButtons));
}
else
{
btnSplit.IsEnabled = true; //this is ultimately run on the UI-thread
}
}
Taken from here:
http://blog.clauskonrad.net/2009/03/wpf-invokerequired-dispatchercheckacces.html
I have a question about timers and threads. I noticed that the timers misbehaving when started within the threads, while the timers are part of the Winform.
Generally I'm interested in problems related threads and timers.
Happy New Year to you all, the answers may be to wait until 2011:)
Sounds like you're using a System.Threading.Timer and using a TimerCallback that performs GUI updates. Is that it?
There are a number of correct ways to deal with this. Use a System.Windows.Forms.Timer and handle its Tick event if you're looking to update the UI. Use a BackgroundWorker, do non-UI work in its DoWork event and then perform UI updates in its RunWorkerCompleted event if you're performing long-running background tasks.
In general, the important thing to understand about multithreading as it pertains to Windows Forms is this: all Windows Forms application have a UI thread, which is the only thread that is allowed to perform UI updates. It is continually processing a queue onto which user actions are pushed and handle via events. When you try to do anything that updates a UI control from any thread besides this thread, you get an exception because this behavior was not planned for in the design of Windows Forms components, and would therefore very likely cause bugs or possibly crash the entire application.
So the approach to multithreading is generally to separate work into two parts, that which can be done in the background (on a non-UI thread) and that which must sent to the queue being processed by the UI thread so that it can be handled in a safe manner. The usefulness of types like System.Windows.Forms.Timer and BackgroundWorker is that they encapsulate many of the difficult details of this process for you, allowing you to focus on the code you want to run.
That's a high level view of how multithreading works with Windows Forms. I'm sure others can provide plenty of references pointing you to more information on the subject (and if nobody else does, maybe I can look some up later).
Comparing the Timer Classes in the .NET Framework Class Library is a good article to read.
Google maybe?
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx