Performance for Timer vs DispatcherTimer - c#

I don't have a specific scenario in mind, but this question just crossed my mind while I was thinking of scenarios where I may want to use a Timer over a DispatcherTimer.
In the scenario where I have to perform come computationally intensive task whenever a timer event fires, and then make minor modifications to UI, would it be better in terms of performance to:
use a regular Timer and then use the application's Dispatcher to
change the UI
use a DispatcherTimer (and possibly do my computationally
intensive work in some async background worker if necessary).
My guess is that keeping the UI thread unblocked for as long as possible will enhance the user experience. If this is advisable, Are there any catches that I should be aware of in such a scenario?
EDIT:
I get the feeling my question was not clear enough, so I'm going to try and add a concrete, albeit made-up example.
Let's say I have to read a large file every 2 minutes, and when I'm done, I have to add an item to a ListBox. Let's say reading/processing the file takes 10-15 seconds, during which I do no UI work. What would be the best approach for something like this?

Main point:
to perform come computationally intensive task
This would indicate not using the DispatcherTimer. It mainly exists to perform small tasks on the main thread and avoid creating another thread.
If you use a DispatcherTimer to start a Backgroundworker you're circumventing its main purpose.
So just use a regular Timer here.

After some more research and analysis, I've come to the conclusion that a regular timer works best in my made-up example. So far, I haven't had to look out for anything specific that would cause potential problems in my code. Having said that, good coding practices never hurt!

Timer generates recurring events in an application
DispatcherTimer is a timer that is integrated into the Dispatcher
queue which is processed at a specified interval of time and at a
specified priority.
Timers are not guaranteed to execute exactly when the time interval occurs, but are guaranteed not to execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes, it is dependent of the other jobs in the queue and their priorities.
If a Timer is used in a WPF application, it is worth noting that the Timer runs on a different thread then the user interface (UI) thread. In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke. Reasons for using a DispatcherTimer opposed to a Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set.

Comparing Timer with DispatcherTimer
Some answers posted here are more specific to your question but I think this link offers some general information and advice.

If you want to change a scalar (not a collection) value binded to UI element, you can do it not only from UI thread (e.g. from Timer delegate). And in this case you don't need to use Dispatcher.Invoke/BeginInvoke.

Another option is to use DispatcherTimer with creating BackgroundWorker class instance on each timer iteration. It also frees you from using Dispatcher.Invoke/BeginInvoke in many cases.

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

Are there alternatives to invoke in WPF when passing data from a different thread?

I know how to pass data from a worker thread to the main thread via Invoke/BeginInvoke.
I can also pull from a thread safe collection with a timer from the main thread.
I prefer using tasks (Task.Factory.StartNewTask()) and using Backgroundworker with them seams a bit clumsy.
Sometimes the gui is a bit laggy which is due to (Begin)Invoke I assume.
Pulling with a timer also doesn't feel like the right way.
Creating a new Backgroundworker for each new task seams also strange.
Are there any other possibilities?
In .NET, memory is shared within an AppDomain, which means all threads can access all data. So, what you're actually doing is controlling access to particular bits of data from particular threads so they don't interfere with each other.
Invoke and BeginInvoke allow you to run code on the UI thread, which is useful because UI controls can only be accessed from the UI thread. BackgroundWorker is another solution, as is SynchronizationContext.
However, they all work by sending known windows messages to the UI message loop. If you call Invoke too often, you send too many messages and the UI thread is swamped which makes the UI "a bit laggy".
If this happens, you must slow down the rate that messages are sent. There are a couple of ways to do this:
1) Call Invoke less frequently: this means waiting for bigger "chunks" of state changes in your background thread before it calls Invoke to update the UI.
2) Use a UI Timer: there is no point in trying to update the UI faster than the human eye can detect. A UI Timer also sends windows messages to the UI message loop, but at a known rate. The Tick handler can then pull the necessary data from shared memory to update the UI.
Both approaches have their strengths and weaknesses. The choice really depends on how easy it is to group state changes in the background thread into bigger chunks, while making sure the UI doesn't miss any state changes.

What are the differences between System.Threading.Timer and creating your own background tick thread in C#

I have a background tick function that is structured as follows:
System.Threading.Thread myTimerThread = new Thread(this.Tick);
private void Tick(){
do{
//do stuff
System.Threading.Sleep(1000L);
}while(true)
}
However, there is also a System.Threading.Timer class that does this for me. What are the differences in using the built in Timer class present in System.Threading rather than creating my own background thread with a Tick function?
The Timer class would be very light weight and more efficient as compared to your own dedicated thread which is sleeping for a specified time inside infinite do while loop.
Do read Thread.Sleep is a sign of a poorly designed program for finding out how Thread.Sleep actually works and how it wastes a complete thread and resources
On the other hand System.Threading.Timer will use ThreadPool thread to execute the timer. Other benefit of using Timer class as described my MSDN
When you create a timer, you can specify an amount of time to wait before the
first execution of the method (due time), and an amount of time to wait between
subsequent executions (period). You can change these values, or disable the timer, using the Change method.
You won't have these benefits in thread based approach
First of all, use the thread pool unless you are performing a long running operation. The difference between your roll your own timer, and System.Threading.Timer is that System.Threading.Timer uses hardware interrupts to know when it is appropriate to perform the tick. It will be more accurate (though a multimedia timer will be even more accurate) than just sleeping for x milliseconds which will have to wait until control is given thread scheduler before your thread will have control.
You should also know that if you are doing anything that will affect the Gui on your thread you should use the appropriate Gui version of the timer otherwise your ticks will not occur on the thread you have to access Gui controls on and you will have to Invoke to get on the correct thread. For windows forms it is System.Windows.Forms.Timers, it is System.Windows.Threading.DispatcherTimer for WPF and Silverlight. For more information on threading and timers I highly recommend Joseph Albahari's free ebook Threading in C#.
You have alot more control using System.Threading.Timer. You can program the timer to check a certain thread or event every say....1/4 of a second, until it runs and then you can dispose of the timer using the dispose method. Its a lot more flexible because you can program it to do whatever you want and it is a lot more accurate.
When you use Thread.Sleep, you really only have one option and that is to force the program to "sleep" for x of seconds. To my knowledge you can not dispose it, time it, coordinate it so it stops early. etc. The bottom line is, even after your program is done running, the Thread.Sleep will continue to force the program to sleep. Threading.Timer can be programmed to stop when the program is finished running.

BackgroundWorker component in services

I know the BackgroundWorker should not be used in Windows Services but would anyone have a good online reference explaining why?
BackgroundWorker relies on a current SynchronizationContext being set in order to function. It's really intended and designed specifically for working with UI code.
It's typically better in a service to self-manage your threads, since there are no UI synchronization issues. Using the threading API (or .NET 4 Task API) is a much better option here.
Well, it's okayish to use a BGW in a service, it just doesn't do anything especially useful. Its reason for being is its ability to raise the ProgressChanged and RunWorkerCompleted events on a specific thread. Getting code to run on a specific thread is a very non-trivial thing to do. You cannot simply inject a call into the thread while it is executing code. That causes horrible re-entrancy problems. The thread has to be 'idle', in a state where inject code doesn't cause trouble.
Having a thread in an idle state is a fairly unnatural condition. You use threads to run code, not for them to be idly spinning its heels. This is however the way a UI thread works. It spends 99% of its time in the message loop, waiting for Windows to tell it to do something. A button click, a paint request, a keyboard press, that sort of thing. While it is inside the message loop, it is in fact idle. A very good time to execute injected code.
Which is what Winforms' Control.Begin/Invoke and WPF's Dispatcher.Begin/Invoke do. They put a delegate in a queue, the queue is emptied and the delegate targets executed by the message loop. The WindowsFormsSynchronizationContext and DispatcherSynchronizationContext classes are the synchronization providers that uses them. Winforms and WPF replace SynchronizationContext.Current with an instance of them. Which in turn gets used by BGW to raise the events. Which makes them run on the UI thread. Which allows you to update the non thread-safe user interface components from a worker thread.
You can probably see where this is heading, a service uses neither. The default synchronization provider doesn't synchronize anything. It simply uses a threadpool thread to call the Send or Post callback. Which is what will happen when you use BGW in a service. Now there is actually no point at all in having these events. You might as well let the DoWork handler call the event handling methods directly. After all, the thread on which DoWork runs is just another threadpool thread as well.
Well, no real harm done, other than making it quite a bit slower.
I've used BackgroundWorker in windows services many times without any ill effect. While its use of SynchronizationContext may be unnecessary, I haven't observed it causing problems or poor performance.

what should i avoid doing on background thread in winforms

besides updating GUI controls from background threads, is there any other operations that should avoid being done on background threads in winforms?
Oh, there are plenty of traps. BGW doesn't do much to protect you from the usual hazards of threaded programming. And adds some of its own:
Variables that are accessed from both the BGW and the UI thread must be protected by a lock.
Do not update a bound data source in a BGW. The control updates will be done on the BGW thread but will not generate an exception.
Don't call ReportProgress() too often. Doing it more than about 1000 times per second will freeze the UI thread. About 25 times/sec is enough.
Careful with the userstate argument you can pass to ReportProgress(). It must not be modified by the BGW after the call.
Don't loop on the IsBusy property in the UI thread, it will deadlock.
The BGW thread will be aborted when the main form closes. Watch out for necessary cleanup.
Be sure to inspect the Error property in the RunWorkerCompleted event, it tells you when something went wrong.
This is sort of broad. Don't do anything in a background thread if you don't need to; that is, don't thread out some code just because you feel like it. Use threads where it is appropriate such as for long running tasks that you do not want to interrupt the GUI and so forth. Also, if you end up just calling Application.DoEvents() from your main UI thread just waiting on a task from another thread, you might think about keeping one thread and doing the work in small pieces in a loop where you would repaint the GUI with DoEvents() calls. This is just a suggesiton; however, of course, many times you do need to create multiple threads.
Perhaps you can ask about particular situations?
Well, the reason you should not update GUI controls on a background thread is that the GUI control classes are not threadsafe. So, you can generalize that: don't mess with instances of non-threadsafe classes from a background thread if there is some other thread that might also use them. (That's broad, I know, but anything that breaks that rule could get you in trouble).
But I think the gist of your question is whether or not you've covered all the bases that Control.Invoke() was created to cover. If so, yes, you have ... Control.Invoke was specifically designed for the fact that controls are not threadsafe, and therefore, other threads should only modify controls via Control.Invoke().
I agree with Bobby that your question is too broad. Instead start with the assumption that if you have to create a worker thread, you're not going to put anything in it except what absolutely has to be there to complete the required task.

Categories

Resources