I was wondering whether Background thread are really helpful if i need to update my GUI regularly (quite often in my case) ?? I'm working on a WPF (C#) app. While opening an old project file I've done all processing on background thread, However GUI shows progress and needs to be refreshed regularly.
So does background thread will really help in this case. What if i move this processing to main thread (as ever otherwise i'm not doing anything, just waiting for file to load) ?
Found !! Thanks,
Well, one thing to consider is not updating the progress quite as often. Is the user going to notice the difference between updating it 100 times a second and updating it 10 times a second? You might want to batch the updates. Having said that, unless the updates are actually becoming problematic in terms of performance, I wouldn't take the complexity hit.
However, if you're doing a significant amount of work you should absolutely have it in a background thread. Otherwise your UI will become unresponsive while that work is carrying on - and depending on some details, the progress updates might not even show at all!
Even though your code may not be doing anything else, the UI thread still wants to be able to respond to events - mouse movements etc.
You should definitely watch the WPF 4 PDC note of 2009. It sounds old, but shows several ways of doing "extensive" tasks in several ways (background worker for example).
http://www.microsoftpdc.com/2009/CL10
You should load the file in a other thread and fire events on progress.
The mainthread should listen to this events and update the GUI.
You shouldn't use background thread if:
Your code takes very short period of time to be noticed by user
Your code takes very long period of time but you don't care about "Not responding" window title and frustrated users.
Speaking seriously they are useful if you want to create responsive user interface. Here is wonderful introductory articles from Lee Campbell: Responsive UIs in WPF - Dispatchers to Concurrency to testability
Related
I have some code which interops with some COM dlls and ActiveX controls, and then fetches me some result. I am trying to run this code in the background in another thread.
But I have a problem, if I use UI thread to achieve this, the application gets blocked, but the time taken is about 5-6 seconds approximately for this operation.
If I move this code into a background thread, the UI remains responsive but the time taken almost doubles to 10-11 seconds. There is nothing different which I am doing, but is there any specific reason why this takes more time.
As of now not able to put any code. I tried increasing the thread priority too. It did not help.
Thanks
You should probably profile this to see when the execution of that background thread actually starts, and what it's actual time-consumption is - start to finish. There're a number of pretty decent profilers that can do this for you. Remember, when you create a separate thread, that doesn't mean that it necessarily fires up right at that instant. And something might be interrupting it (such as something higher in priority). Plus, when you executed it on your UI thread, it had your UI thread's priority: what priority are you setting the background-thread to? As DeveloperGuo suggests - you should probably instantiate the COM object on that background thread: if that object doesn't have to hang around, then it is generally cleaner and more efficient to make that thread have full responsibility for the COM objects and other resources that it uses, and just provide a higher-level abstract API for the rest of your program-code to use. These are just generic suggestions - can't get more specific without seeing code.
I'm using a DataGridView and some operations that I do cause it to become unresponsive for periods of time. Normally I would put data processing in its own thread to make the form more responsive, but in this case it's the DataGridView itself that's taking so long.
This leads me to wonder whether it's possible to have the main form on one thread and the DataGridView on another thread so it doesn't prevent the main form from responding.
I completely understand that doing so is probably not 'safe' and likely opens up a can of worms that makes it hardly worth trying and I fully expect this post will be getting down votes for merely suggesting such a ridiculous idea.
Is this possible? And if so how would you go about it?
EDIT: I figured out how to fix the problem at hand. The short answer was to use a flag when setting the RowCount so CellValueNeeded() can bail out immediately. There's really more to the story and I had already been doing this partially, but that's the gist of it.
Short answer is no, because the control needs to interact with other controls (or at least the window), and they all need to be on the same thread.
Doing so seems to imply that you're doing processing on the UI thread, which itself is also a big no-no. You should run all of your major processes on their own thread, and then save the final presentation for the UI thread -- work on one thread, screen updates on another.
It is definitely possible to have multiple UI threads in a given application. However it is not possible to compose UI components from different threads onto the same Form. For a given form all of the components must be on the same thread
The best way to fix this problem is to move the data processing itself onto a separate thread. Only do the absolute minimum to update the UI from the UI thread. That should help with the responsiveness
take a look into use of virtualization in the grid.
And please give code sample to what operation is taking too long!
No, but from events fired from the dataGridView you could send a worker to perform async tasks and then update the dataGridView using the controls Invoke method from the worker thread
I have a software in C# I'm writing and every time its doing a hard task and I switch windows to let it complete the window screws up. Not sure how to word it but all of the buttons disappear or become "holes" . I know the application is running because the progress bar shows up again after a while. How do I fix this? I've been searching and I'm sure it has something to do with doubleBuffering.
you normally solve this by executing your resource intensive process in a separated thread than the main UI thread, in this way the UI thread can refresh the UI as needed and your long lasting operation is completed in parallel. After the background / worker thread has completed its task the control flow will return to the application.
Things are a bit more complicated when you want to update the status bar in the UI thread from the worked thread, usually you have to use the Invoke methods because you definitely should not even try to access and modify UI controls from another thread.
a bit cheaper method which kind of works but can have some issues from time to time is to include in your long lasting operation a call to Application.DoEvents() from time to time, for example if you are in a loop, every few iterations of the loop (depends on how much time it takes to execute a single iteration and on how many iterations you have in total); this method works and saves you completely from start working with multiple threads but is also considered less reliable.
As LarsTech already pointed out, use the BackgroundWorker-Class, especially for tasks which take longer than just a few seconds.
Make sure to use ReportProgress in your Backgroundworker to notify your Progressbar.
Good links worth studying:
http://www.albahari.com/threading/part3.aspx
http://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners
In my C# project I have a form that is displayed which shows a progress bar.
Some processing is then done which involves communication over the internet.
While this processing is occurring the form says "Not Responding" when run in Win 7, in XP the form just goes white.
Either way, it is not acceptable.
Do I need to use threads to solve this problem?
What are some of the basics of threads that I would need to use in this scenario?
Your processing must be done within a thread.
Out of your thread you have to invoke your progress bar to show the progress.
progressBar1.Invoke((MethodInvoker)delegate
{
progressBar1.Value = (int)((i / limit) * 100);
});
Yes you have to use threads to keep your UI responsive while something gets done in background. But this question cannot be just answered just like "use Threads to solve it", because there are a lot of forms in which you could use threads. (Backgroundworker, Threadpool, Asynch IO, Creating a Thread, Task Parallel Library, CCR, and a lot more you could imagine for every kind of parallelization scenarios).
As you said you are doing some processing which needs connecting to internet. Where does the most amount of time spent? is it IO over network which takes most time in that case probably Asynchronous IO makes a lot of sense. If time spent is in one huge processing operation then Background worker is perfect, but if this processing can be further broken down into smaller chunks of parallel processing tasks then TPL or ThreadPool is preferred. Till now I am talking only about some processing which happens on Windows forms event, and keep the UI responsive. But based on the scenario there are numerous other options you could use to make threading work for you.
Asynch IO doesnt look like you are doing threading but it more matches with eventing model of winforms. So you could look at that if you are very comfortable with event based programming.
Threadpool looks more like a queue of workers to which you could keep throwing all the work needs to be done, and the framework figures out how many threads to run based on the kind of machine you are using (dual core, quad core etc) and it would get your work items doen in optimal way.
Bottom line its not one answer to use one over other, instead based on the kind of problem you are solving threading model needs to be decided on.
A cheaper option is to add the line Application.DoEvents() inside whatever loops your app is running, which will cause it to process messages each time it gets there.
If you use System.Net.WebClient, you can use DownloadDataAsync() to communicate in a non blocking way.
The System.Net.Sockets.Socket class proviede non blocking communication, too.
Sockets example
WebClient example
Yes, better way is use BackGroundWorker component. It is wrapper over threads, so you don't need to manage threads. You can get more info from Background worker on MSDN
As long as the program remain in the function to process something, the UI will not update. That is why you may need to start a background thread, so that your UI can continue functioning while your background thread can do the work. An alternatively is to use asynchronous functions.
example of background thread
From your description I'll assume that all your work is currently being done on a single thread, the main thread which is also used for your GUI.
The progress bar can only update when that main thread gets a chance to check its state and apply any expected changes.
Therefore it is important that your processing work does not occupy the main thread for extended periods of time.
There are two main approaches to handling this:
Stepping the processing activity.
Break down the processing step into a number of serial tasks - each short in nature.
Progressively call each of these serial tasks in the OnIdle event on your main thread.
Using a background thread.
See other answers giving more detail on how this would work.
The stepping approach can be useful if you want to avoid the sublties of thread synchronisation. The threading approach is probably better but only essential if it is impossible to guarantee serial short steps.
I've been working on the same project now since Christmas 2008. I've been asked to take it from a Console Application (which just prints out trace statements), to a full Windows App. Sure, that's fine. The only thing is there are parts of the App that can take several minutes to almost an hour to run. I need to multithread it to show the user status, or errors. But I have no idea where to begin.
I've aready built a little UI in WPF. It's very basic, but I'd like to expand it as I need to. The app works by selecting a source, choosing a destination, and clicking start. I would like a listbox to update as the process goes along. Much in the same way SQL Server Installs, each step has a green check mark by its name as it completes.
How does a newbie start multithreading? What libraries should I check out? Any advice would be greatly appreciated.
p.s. I'm currently reading about this library, http://www.codeplex.com/smartthreadpool
#Martin: Here is how my app is constructed:
Engine: Runs all major components in pre-defined order
Excel: Library I wrote to wrap COM to open/read/close/save Workbooks
Library: Library which understands different types of workbook formats (5 total)
Business Classes: Classes I've written to translate Excel data and prep it for Access
Db Library: A Library I've written which uses ADO.NET to read in Access data
AppSettings: you get the idea
Serialier: Save data in-case of app crash
I use everything from LINQ to ADO.NET to get data, transform it, and then output it.
My main requirement is that I want to update my UI to indicate progress
#Frank: What happens if something in the Background Worker throws an Exception (handled or otherwise)? How does my application recieve notice?
#Eric Lippert: Yes, I'm investigating that right now. Before I complicate things.
Let me know if you need more info. Currently I've running this application from a Unit Test, so I guess callig it a Console Application isn't true. I use Resharper to do this. I'm the only person right now who uses the app, but I'd like a more attractive interface
I don't think you specify the version of the CLR you are using, but you might check out the "BackgroundWorker" control. It is a simple way to implemented multiple threads.
The best part, is that it is a part of the CLR 2.0 and up
Update in response to your update: If you want to be able to update the progress in the UI -- for example in a progress bar -- the background worker is perfect. It uses an event that I think is called: ProgressChanged to report the status. It is very elegant. Also, keep in mind that you can have as many instances that you need and can execute all the instances at the same time (if needed).
In response to your question: You could easily setup an example project and test for your question. I did find the following, here (under remarks, 2nd paragraph from the caution):
If the operation raises an exception
that your code does not handle, the
BackgroundWorker catches the exception
and passes it into the
RunWorkerCompleted event handler,
where it is exposed as the Error
property of
System.ComponentModel..::.RunWorkerCompletedEventArgs.
Threading in C# from Joseph Albahari is quite good.
This page is quite a good summary of threading.
By the sound of it you probably don't need anything very complex - if you just start the task and then want to know when it has finished, you only need a few lines of code to create a new thread and get it to run your task. Then your UI thread can bumble along and check periodically if the task has completed.
Concurrent Programming on Windows is THE best book in the existence on the subject. Written by Joe Duffy, famous Microsoft Guru of multithreading. Everything you ever need to know and more, from the way Windows thread scheduler works to .NET Parallels Extensions Library.
Remember to create your delegates to update the UI so you don't get cross-threading issues and the UI doesn't appear to freeze/lockup
Also if you need a lot of notes/power points/etc etc
Might I suggest all the lecture notes from my undergrad
http://ist.psu.edu/courses/SP04/ist411/lectures.html
The best way for a total newcomer to threading is probably the threadpool. We'll probably need to know a little more about these parts to make more in depth recommendations
EDIT::
Since we now have a little more info, I'm going to stick with my previous answer, it looks like you have a loads of tasks which need doing, the best way to do a load of tasks is to add them to the threadpool and then just keep checking if they're done, if tasks need to be done in a specific order then you can simply add the next one as the previous one finishes. The threadpool really is rather good for this kind of thing and I see no reason not to use it in this case
Jason's link is a good article. Things you need to be aware of are that the UI can only be updated by the main UI thread, you will get cross threading exceptions if you try to do it in the worker thread. The BackgroundWorker control can help you there with the events, but you should also know about Control.Invoke (or Control.Begin/EndInvoke). This can be used to execute delegates in the context of the UI thread.
Also you should read up on the gotchas of accessing the same code/variables from different threads, some of these issues can lead to bugs that are intermittent and tricky to track down.
One point to note is that the volatile keyword only guarantees 'freshness' of variable access, for example, it guarantees that each read and write of the variable will be from main memory, and not from a thread or processor cache or other 'feature' of the memory model. It doesnt stop issues like a thread being interrupted by another thread during its read-update-write process (e.g. changing the variables value). This causes errors where the 2 threads have different (or the same) values for the variable, and can lead to things like values being lost, 2 threads having the same value for the variable when they should have different values, etc. You should use a lock/monitor (or other thread sync method, wait handles, interlockedincrement/decrement etc) to prevent these types of problems, which guarantee only one thread can access the variable. (Monitor also has the advantage that it implicitly performs volatile read/write)
And as someone else has noted, you also should try to avoid blocking your UI thread whilst waiting for background threads to complete, otherwise your UI will become unresponsive. You can do this by having your worker threads raise events that your UI subscribes to that indicate progress or completion.
Matt
Typemock have a new tool called Racer for helping with Multithreading issues. It’s a bit advanced but you can get help on their forum and in other online forums (one that strangely comes to mind is stackoverflow :-) )
I'm a newbie to multithreading as well, but I agree with Frank that a background worker is probably your best options. It works through event subscriptions. Here's the basics of how you used it.
First Instantiate a new background worker
Subscribed methods in your code to the background workers major events:
DoWork: This should contain whatever code that takes a long time to process
ProgressChanged: This is envoked whenever you call ReportProgress() from inside the method subscribed to DoWork
RunWorkerCompleted: Envoked when the DoWork method has completed
When you are ready to run your time consuming process you call the RunAsync() method of the background worker. This starts DoWork method on a separate thread, which can then report it's progress back through the ProgressChanged event. Once it completed RunWorkerComplete will be evoked.
The DoWork event method can also check if the user somehow requested that the process be canceled (CanceLAsync() was called)) by checking the value of the CancelPending property.