Background thread takes more time than UI thread - c#

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.

Related

Redrawing windows application

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

Other ways to update UI from thread in C#

My application is heavily depended on threads to do the complex processing of very large data. The UI needs to be updated as the processing is being done. I know and tried to used BackgroundWorker's OnProgressChanged and RunWorkerCompleted methods to update the UI. Also using Invoke method of the UI thread to update. Everything seems to work fine on Win XP 32 bit and 64 bit OS. On Win Vista and Win 7 (32 and 64 bit), the application randomly hangs while updating the UI by using Invoke method.
Does the behavior of Invoke changes on different Win OS?
What are the other ways of updating UI from thread apart from Invoke?
Thanks
Does the behavior of Invoke changes on different Win OS?
It should not, no. But, threading problems can materialize in very unpredictable ways. It is possible that you have an unidentified problem.
What are the other ways of updating UI from thread apart from Invoke?
Using Invoke or BeginInvoke are way overused especially when trying to report simple progress information to the UI thread. If you search for some of my answers related to the subject you will see that I rip on this approach all of the time. And for good reason since their are many disadvantages to using this technique. It is unfortunate that BackgroundWorker uses this mechanism exclusively for updating the UI through its ProgressChanged event.
One alternate method is to have your worker thread publish progress information into a shared variable and have the UI thread poll for it periodically via a timer. Here are some of my usual talking points in justifying this approach over the marshaling techniques.
Invoke and BeginInvoke are expensive operations.
The UI thread gets to dictate when and how often to update the form and its controls.
It eliminates the tight coupling between UI and worker threads that ISynchronizeInvoke imposes.
There is no risk of overrunning or saturating the UI message queue with a bunch of marshaling operations.
You get more throughput on the worker thread since it does not have to wait for response as would be the case with Invoke.
Not sure what's going wrong, but you could always just have a System.Windows.Forms.Timer running that updates the GUI periodically; use some member variables to pass raw data between threads, inside locks if necessary. Not the most elegant solution, but it might give you a different perspective into what's hanging since the threads are more independent this way, rather than relying on a background thread to Invoke your main thread.
You could try using one of the Invoke() or BeginInvoke() overloads that takes a Dispatcher.Priority enum as a parameter. If you select a parameter such as 'Background' you should see your application is still responsive. The only issue then becomes ensuring you are servicing your incoming data at an adequate rate without an ever increasing queue.
Another option would be to forego the multithreading entirely. If your long-running operation can be broken up into chunks, do it in the GUI thread and use Application.DoEvents() when you want to update the GUI.
I used to dislike use of that method since it could not only update the GUI but also start responding to user input, kicking off timers, etc., but ultimately it's no less safe than using a background thread, which allows the GUI to start doing anything at any time. So probably after each call of Application.DoEvents() you'd need to check _canceled or whatever. (I eventually decided I dislike the existence of this method, since it eliminates the guarantees of linear execution order, than the use of it).
Of course you lose multicore support this way, so it'd affect performance if you're trying to run lots of background ops at the same time.

C#: "not responding" window when program is doing some background processing

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.

Background Worker C# winform

is it a bad idea to load everything in from the background worker??
Current code is Executed on Form_load. we are pulling a lot of data from webservice. some long running works are in background worker.
would it be a bad idea to load everything from background worker no matter how small or big the code is??
every function to run in background worker?
or is this going to make this code messy and treading nightmare.
Thank you.
The size of the code is not a metric you should use to determine whether to perform work on a separate thread. Worst case length of execution is.
First, there aren't many UI designs where firing off a bunch of work on Form_Load is really desirable. If it's possible, I typically either:
Initiate that work prior to opening the form directly in response to a user action.
Move all of the work into the background and asynchronously update (bind?) the results to the form.
Delay the work until the user specifically performs some action which requires it.
Your users will want/expect your forms to be extremely fast and responsive regardless of how much work is being done. Executing potentially long-running operations during Form_Load is always going to result in a bad user experience.
BackgroundWorker is only one mechanism for performing work asynchronously, there are many others. You should choose the one that is most appropriate for each situation.
BackgroundWorker is normally used to make a Winforms UI more responsive. You can use it for background processing in a web application, but I don't; I use a ThreadPool in a Windows Service.
Its good to stick potentailly long-running code into a background worker so that your application remains responsive, but there is no need to put everything as a background worker.
If your code calls a web service (or any sort of external system that might time out), or does something that it likely to take longer than a few seconds, then that would be a good candidate for putting into a background worker, however if anything consistently takes less than a second or so to execute I proabably wouldn't bother.
A Background Worker will take extra time to create and destroy the thread for the background worker. If it is a small piece of code (processing-wise) it may be faster to use the main UI thread.
If maintainability is the key, perhaps using Background workers for processing may be the solution. A custom framework of sorts that automatically dealt with the detail may make the code even more maintainable.
It depends on several factors:
The number of small/large pieces of code - this will effect the number of threads running at the same time.
The importance of responsiveness and performance for the application
The importance of maintainability/scalability for the application.
Whether it is a good idea or not depends very much on the specifics of your problem. Do you have to pull all the data in one call or can you do it in independent chunks?
If it is one big long running web service call, then putting it on a thread won't do anything for you. Your best case would be several independent, long running chunks that take approximately the same amount of time to return.
Also, in webforms (since you mention Page_Load) IIRC you will be sharing the thread pool with asp.net, and you may cause your app to become less responsive overall at some threshold of concurrent requests/users.
Personally, I wouldn't put code into a worker thread unless the code comprised a specific process was interfering with UI responsiveness. There's no reason I can think put everything on a worker thread. Generally you only have responsiveness issues when you're waiting for an external resource like a web service (unless you are calculating prime numbers on Form_Load :-).
If you haven't explored asynchronous web service calls, I would recommend taking a look. The asynchronous calls will handle your threading for you - always a good thing.
It sounds like, from your reference to "Page_Load", that you are implementing this in a ASP.NET web form. If that is the case and you are trying invoke a web service asynchronously then you should use the Begin and End invoke functions of the service. This works especially well if you need to call multiple web service at the same time instead of calling them one at a time synonymously.
Enjoy!

.NET Thread Pool - Unresponsive WinForms UI

Scenario
I have a Windows Forms Application. Inside the main form there is a loop that iterates around 3000 times, Creating a new instance of a class on a new thread to perform some calculations. Bearing in mind that this setup uses a Thread Pool, the UI does stay responsive when there are only around 100 iterations of this loop (100 Assets to process). But as soon as this number begins to increase heavily, the UI locks up into eggtimer mode and the thus the log that is writing out to the listbox on the form becomes unreadable.
Question
Am I right in thinking that the best way around this is to use a Background Worker?
And is the UI locking up because even though I'm using lots of different threads (for speed), the UI itself is not on its own separate thread?
Suggested Implementations greatly appreciated.
EDIT!!
So lets say that instead of just firing off and queuing up 3000 assets to process, I decide to do them in batches of 100. How would I go about doing this efficiently? I made an attempt earlier at adding "Thread.Sleep(5000);" after every batch of 100 were fired off, but the whole thing seemed to crap out....
If you are creating 3000 separate threads, you are pushing a documented limitation of the ThreadPool class:
If an application is subject to bursts
of activity in which large numbers of
thread pool tasks are queued, use the
SetMinThreads method to increase the
minimum number of idle threads.
Otherwise, the built-in delay in
creating new idle threads could cause
a bottleneck.
See that MSDN topic for suggestions to configure the thread pool for your situation.
If your work is CPU intensive, having that many separate threads will cause more overhead than it's worth. However, if it's very IO intensive, having a large number of threads may help things somewhat.
.NET 4 introduces outstanding support for parallel programming. If that is an option for you, I suggest you have a look at that.
More threads does not equal top speed. In fact too many threads equals less speed. If your task is simply CPU related you should only be using as many threads as you have cores otherwise you're wasting resources.
With 3,000 iterations and your form thread attempting to create a thread each time what's probably happening is you are maxing out the thread pool and the form is hanging because it needs to wait for a prior thread to complete before it can allocate a new one.
Apparently ThreadPool doesn't work this way. I have never checked it with threads before so I am not sure. Another possibility is that the tasks begin flooding the UI thread with invocations at which point it will give up on the GUI.
It's difficult to tell without seeing code - but, based on what you're describing, there is one suspect.
You mentioned that you have this running on the ThreadPool now. Switching to a BackgroundWorker won't change anything, dramatically, since it also uses the ThreadPool to execute. (BackgroundWorker just simplifies the invoke calls...)
That being said, I suspect the problem is your notifications back to the UI thread for your ListBox. If you're invoking too frequently, your UI may become unresponsive while it tries to "catch up". This can happen if you're feeding too much status info back to the UI thread via Control.Invoke.
Otherwise, make sure that ALL of your work is being done on the ThreadPool, and you're not blocking on the UI thread, and it should work.
If every thread logs something to your ui, every written log line must invoke the main thread. Better to cache the log-output and update the gui only every 100 iterations or something like that.
Since I haven't seen your code so this is just a lot of conjecture with some highly hopefully educated guessing.
All a threadpool does is queue up your requests and then fire new threads off as others complete their work. Now 3000 threads doesn't sounds like a lot but if there's a ton of processing going on you could be destroying your CPU.
I'm not convinced a background worker would help out since you will end up re-creating a manager to handle all the pooling the threadpool gives you. I think more you issue is you've got too much data chunking going on. I think a good place to start would be to throttle the amount of threads you start and maintain. The threadpool manager easily allows you to do this. Find a balance that allows you to process data while still keeping the UI responsive.

Categories

Resources