This is a continuation of threading in C# covered here. In this article I am going to cover more usages of threading, particularly timers and UI threading.

Multi-threaded Timers live in System.Threading.Timer and System.Timers and they represent one of the most common use case for repeatedly executing an action such as polling information and checking for a resource change. However the latter one is a wrapper around the first one and I’ll cover only the second one.

[code lang=”csharp”]
Timer timer = new Timer();

// define interval of execution
var interval = TimeSpan.FromSeconds(5);
timer.Interval = interval;

// assign a method to the elapsed event
timer.Elapsed += PerformAction;
timer.Start(); // Start the timer
timer.Stop(); // Stop the timer
timer.Dispose(); // Permanently stop the timer

// this is fired every 5 seconds
void PerformAction(object sender, System.Timers.ElapsedEventArgs e){
// example of updating WPF UI controls from another thread
Action action = () => txtMessage.Text = message;
Dispatcher.Invoke (action);
}
[/code]

Such timers use the thread pool to allow for only a few threads to be used for many timers and thus avoiding wasting threads. That means that the event can be fired on a different thread every time and because of that they will fire regardless if the previous callback finished or not and that is dangerous. Why? Because dead locks can happen and then multiple event firings can and will ultimately crash your application by using all threads available. I’ve seen this happening therefore those event handlers must be thread safe.
Those timers are fairly precise within a 10-20ms range depending on OS, system load.

There is a catch with this one though: you can not update controls directly, whether they are Windows Forms control or WPF controls and you’ll have to use Control.Invoke and Dispatcher.Invoke respectively.

Single-threaded timers live in System.Windows.Forms.Timer  and System.Windows.Threading.DispatcherTimer namespaces and their main purpose is to get rid of the thread safe issue. They fire on the same thread as the one that created them which is basically your application. Beside that there are other advantages such as you don’t have to worry about using Control.Invoke or Dispatcher.Invoke in order to update your UI elements as those live on the same thread as you UI and they won’t fire until previous tick completed. That being said there is one huge downside, that is performing heavy work in the timer tick will render your application ultimately unresponsive. This makes them suitable only for small jobs such as counters or things like that.

Speaking of UIs you almost have no choice but using threading and the best practice there is to use one(or a few) UI threads and delegate any heavy lifting on background threads which at the end update the UI controls with the relevant data.

 

That’s all for now, see you on next article on dead locking, concurrency and concurrent collections. I have the feeling it’s going to be a lengthy one. Stay safe, stay thread safe!

Simple Share Buttons