I have a timer, that triggers a timed event that iterates through a TreeView
and pings all the IP addresses associated with each node.
I want this to be done in the background on a separate thread. I (probably wrongly) thought that an OnTimedEvent exists on a separate thread to the UI.
However, when my program starts, it is responsive. Then as soon as the timed event triggers the UI becomes unresponsive, doesn't crash but doesn't regain responsiveness until the program is stopped in the debugger and ran again.
I've been messing around with async
and await
in order to get the required behaviour however I am unable to achieve this.
Here's how I initialise the Timer currently.
public Form1()
{
InitializeComponent();
StartTimer();
}
private async void StartTimer()
{
aTimer = new System.Timers.Timer(15000);
await Task.Run(() => aTimer.Elapsed += OnTimedEvent);
aTimer.AutoReset = true;
aTimer.Enabled = true;
aTimer.SynchronizingObject = this;
}
And the OnEventTimed method
private async void OnTimedEvent(Object source, ElapsedEventArgs e)
{
// Iterate through all root nodes
foreach (TreeNode tn in mainTree.Nodes)
{
TreeNodeCollection rootNodes = ((TreeNode)tn).Nodes;
foreach (TreeNode node in rootNodes)
{
// Create ping object
System.Net.NetworkInformation.Ping pinger = new();
PingReply pingReply;
if (node.Tag != null)
{
pingReply = pinger.Send(node.Tag.ToString());
if (pingReply.Status.ToString().Contains("Success"))
{
UpdateUI(node, 1); // If successful, set the image index to show green
}
else if (pingReply.Status.ToString().Contains("Failed"))
{
UpdateUI(node, 2);
}
}
}
// Iterate through all the children of the 'root' nodes
foreach (TreeNode child in tn.Nodes)
{
// Extract all nodes from these children
TreeNodeCollection myNodes = ((TreeNode)child).Nodes;
// Create ping object
System.Net.NetworkInformation.Ping pinger = new();
PingReply pingReply;
// Iterate through each of the nodes, send a ping request and then update the UI based on the result of the ping
foreach (TreeNode node in myNodes)
{
if (node.Tag != null)
{
pingReply = pinger.Send(node.Tag.ToString());
if (pingReply.Status.ToString().Contains("Success"))
{
UpdateUI(node, 1); // If successful, set the image index to show green
}
else if (pingReply.Status.ToString().Contains("Failed"))
{
UpdateUI(node, 2);
}
}
}
}
}
}
I am trying to use await Task.Run(() => aTimer.Elapsed += OnTimedEvent);
but it's not giving me the behaviour I expect any help would be appreciated