Comparing Timer with Dispatchertimer

Comparing Timer with DispatcherTimer

Windows.Forms.Timer uses the windows forms message loop to process timer events. It should be used when writing timing events that are being used in Windows Forms applications, and you want the timer to fire on the main UI thread.

DispatcherTimer is the WPF timing mechanism. It should be used when you want to handle timing in a similar manner (although this isn't limited to a single thread - each thread has its own dispatcher) and you're using WPF. It fires the event on the same thread as the Dispatcher.

In general, WPF == DispatcherTimer and Windows Forms == Forms.Timer.

That being said, there is also System.Threading.Timer, which is a timer class that fires on a separate thread. This is good for purely numerical timing, where you're not trying to update the UI, etc.

Performance for Timer vs DispatcherTimer

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!

DispatcherTimer vs a regular Timer in WPF app for a task scheduler

DispatcherTimer is the regular timer. It fires its Tick event on the UI thread, you can do anything you want with the UI. System.Timers.Timer is an asynchronous timer, its Elapsed event runs on a thread pool thread. You have to be very careful in your event handler, you are not allowed to touch any UI component or data-bound variables. And you'll need to use the lock statement where ever you access class members that are also used on the UI thread.

In the linked answer, the Timer class was more appropriate because the OP was trying to run code asynchronously on purpose.

C# WPF Dispatcher Timer Tick in Separate Thread

Make the Tick handler async and await the long-running call:

private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
await Task.Run(() =>
{
// make query here
});

// update the UI outside the Task
_notifyIcon.Text = "Current Issues: " + output;
}

Even better would be to directly call async methods, like

private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
...
dataReader = await command.ExecuteReaderAsync();
...
}

Efficiency of DispatcherTimer versus Thread.Sleep

The DispatcherTimer will invoke a method on your UI thread every N [unit of time]. Thread.Sleep will actually sleep the thread completely. The difference is that with the former, the thread continues, then invokes the Tick event and the latter stops the Thread from doing anything.

It's important to realise that the UI Thread is busy rendering the UI and running your code; hence, a sleep in the UI thread will be perceived as an application hang.

Date comparison within timer

You only compare the times every second - the milliseconds will still be different (especially assuming the turn-on time you compare to most likely doesn't use milliseconds). To compare in a second resolution you could do something like this:

DateTime currentTime = DateTime.Now;
currentTime = currentTime.AddMilliseconds(-currentTime.Millisecond);

Issue with DispatcherTimer for a Countdown clock

Do not subscribe to the DispatcherTimer every time you call CountDown.

DispatcherTimer timeLeft;
int timesTicked = 60;

public QuickPage()
{
timeLeft = new Dispatcher();
timeLeft.Tick += timeLeft_Tick;
timeLeft.Interval = new TimeSpan(0,0,0,1);
}

private void QuestionGenerator()
{
timeLeft.Start();

if (iAsked < 6)
{
//Code to generate random question
}
}

Dispatch timer won't work

You need to fix the event handler signature. It's missing the sender and the type of the second parameter is just object. (See the documentation.)

void timer_Tick(object sender, object e)
{
TimeRefresh();
}

You also need to add a using Windows.UI.Xaml; to the top of your class, or instantiate the timer using the full namespace:

Windows.UI.Xaml.DispatcherTimer timer = new Windows.UI.Xaml.DispatcherTimer();

If anyone stumbles on this and is using WPF, it has it own DispatchTimer. Make sure you're referencing "WindowsBase" (should be there by default). The signature is slightly different.

void timer_Tick(object sender, EventArgs e)
{
TimeRefresh();
}

The namespace it lives in is different too. Either add using System.Windows.Threading; to the top, or qualify with the full namespace:

System.Windows.Threading.DispatcherTimer timer
= new System.Windows.Threading.DispatcherTimer();

If you're using WinForms, you want to use a different timer. Read this for the difference between the WinForms Timer and the WPF DispatchTimer.



Related Topics



Leave a reply



Submit