Relatively new to c#. I made a windows form that monitors for changes to a change in a file. The program takes up 30% of my CPU and I would like to make it run a little lighter. After running the diagnostic session, I can see that Run() is using almost half of the program's resources. Is there a way I can optimize this?
static void Run()
{
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
watcher.Path = Path.GetDirectoryName(path);
watcher.Filter = Path.GetFileName(path);
watcher.Changed += OnChanged;
watcher.Renamed += OnRenamed;
watcher.EnableRaisingEvents = true;
Debug.WriteLine("Running Reader");
while (!cts.Token.IsCancellationRequested) ;
}
}
Here is my CPU usage.
My script to close the thread is also pretty heavy using almost 30%
static CancellationTokenSource cts = new CancellationTokenSource();
private async void buttonRun_Click(object sender, EventArgs e)
{
buttonRun.Enabled = false; // Disable the button to prevent multiple clicks
listBoxStatus.Items.Add($"Line Reader Started! \t Time: {DateTime.Now}");
listBoxStatus.Items.Add("");
status = "Running";
statusApplier();
try
{
await Task.Run(() =>
{
LogApplicationStart();
LoadComparisonFileLines();
Run();
}, cts.Token);
}
catch (OperationCanceledException)
{
listBoxStatus.Items.Add($"Task was cancelled! \t Time: {DateTime.Now}");
}
catch (Exception ex) // Catch any other exceptions
{
listBoxStatus.Items.Add($"An error occurred: {ex.Message}");
}
finally
{
cts.Dispose(); // Dispose the CancellationTokenSource
cts = new CancellationTokenSource(); // Reset the token source
buttonRun.Enabled = true; // Enable the button after the task is completed or if an error occurs
if (listBoxStatus.Items.Count > 0 && listBoxStatus.Items[listBoxStatus.Items.Count - 1].ToString().Contains("Change"))
{
listBoxStatus.Items.Add("");
}
listBoxStatus.Items.Add($"Line Reader Ended! \t Time: {DateTime.Now}");
listBoxStatus.Items.Add("");
status = "Stopped";
statusApplier();
LogApplicationEnd();
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
cts.Cancel(); // Cancel the task
}
I greatly appreciate any help. Thanks
I do not know how to use FileSystemWatcher more efficiently than I am already using it
The culprit causing high CPU usage is the while loop, and in fact, there should not be such an almost endless empty loop in the program.
The simplest solution for your code is to replace this loop with
cts.WaitHandle.WaitOne();
But there is another issue with your code. Your logic is to use one button to start watching and another button to stop it, so you should put the finally
part and the part that disposes the FileSystemWatcher
in the callback of the stop button. This CancellationTokenSource
is redundancy.