Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Console Application takes of a lot of CPU ressource

I have a very simple console app, that will look into a folder and after a few seconds it will delete all files.

The code

private static void Main(string[] args)
    {
      ILogger logger = new LoggerWriter(ConfigurationManager.AppSettings["Log"]);
      Task.Factory.StartNew(() =>
      {
        while (true)
        {
          var time = int.Parse(ConfigurationManager.AppSettings["Interval"]);
          Thread.Sleep(time);
          var directory = new DirectoryInfo(ConfigurationManager.AppSettings["Path"]);
          foreach (var file in directory.GetFiles())
          {
            file.Delete();
            var log = new Logger {DateTime = DateTime.Now, Action = $"File {file.FullName} will be deleted."};
            logger.Write(log);
          }
        }
      }, TaskCreationOptions.LongRunning).ContinueWith(t =>
      {
        if (t.Exception != null)
          Console.WriteLine(t.Exception.Message);
      });


      Console.WriteLine("Press Ctrl+C to stop.");

      while (
        !(Console.KeyAvailable && (Console.ReadKey(true).Key == ConsoleKey.C) &&
          (Console.ReadKey(true).Modifiers == ConsoleModifiers.Control)))
      {
        // do something
      }
    }
  }

When I run the application on the windows server 2008 with .NET 4 the task manager shows following:

enter image description here

When I would use the FileWatcher, it is the same scenario. What is wrong?

like image 447
softshipper Avatar asked Dec 28 '25 07:12

softshipper


2 Answers

It is definitely the way you are handling the Control-C:

  while (
    !(Console.KeyAvailable && (Console.ReadKey(true).Key == ConsoleKey.C) &&
      (Console.ReadKey(true).Modifiers == ConsoleModifiers.Control)))
  {
    // do something
  }

This loop will give you 50% cpu time.

Something like this will fix that:

Console.CancelKeyPress += delegate {
    // call methods to clean up
};

Applied to your code:

Console.WriteLine("Press Ctrl+C to stop.");
var exitEvent = new ManualResetEvent(false);

Console.CancelKeyPress += (sender, eventArgs) => {
                              eventArgs.Cancel = true;
                              exitEvent.Set();
                          };

exitEvent.WaitOne();

To make it complete you have to cancel the task you started correctly in the CancelKeyPress eventhandler

like image 170
Peter Avatar answered Dec 30 '25 22:12

Peter


Your second while loop is a dead loop, hence the high CPU usage. In fact, Ctrl+C is the default break key for a console application, you don't need to write code to "implement" this function.

By the way, from your code I think you want to delete files in a specific directory in a given interval. Take a look at FileSystemWatcher, it will get notified when the watching directory is modified.

like image 22
Cheng Chen Avatar answered Dec 30 '25 23:12

Cheng Chen