The way you are doing it will work just fine. The documentation for Sytem.Timers.Timer
says:
If the SynchronizingObject property is null
, the Elapsed event is raised on a ThreadPool thread.
The SynchronizingObject
property is null
by default, so your Elasped
event will run on a ThreadPool thread, not on the UI thread. That means it will not stop your application from responding to user input.
If there is a chance that ElapsedTime()
will run longer than your interval, and you don't want the events overlapping, then you can set AutoReset
to false
and reset it manually at the end of ElapsedTime()
. Just make sure that everything is wrapped in a try
/catch
block, otherwise the timer won't get reset if there's an exception. My code below shows how that would look.
You don't need to use async
/await
anywhere here. Since it won't be running on the UI thread, using asynchronous code won't really help you any. In a desktop app, it's not a big deal to have a separate (non-UI) thread wait.
public class Timer
{
private System.Timers.Timer timer;
private void InitTimer()
{
timer = new System.Timers.Timer(4000);
timer.Elapsed += ElapsedTime;
timer.AutoReset = false;
timer.Enabled = true;
}
private void ElapsedTime()
{
try {
//send request and update data
}
catch (Exception e)
{
//log the error
}
finally
{
//start the timer again
timer.Enabled = true;
}
}
}