控制台应用程序占用大量 CPU 资源

Console Application takes of a lot of CPU ressource

我有一个非常简单的控制台应用程序,它会查看文件夹并在几秒钟后删除所有文件。

代码

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
      }
    }
  }

当我 运行 windows 服务器 2008 上的应用程序与 .NET 4 任务管理器显示如下:

当我使用FileWatcher时,也是同样的场景。怎么了?

您的第二个 while 循环是一个死循环,因此 CPU 使用率很高。事实上,Ctrl+C 是控制台应用程序的默认中断键,您不需要编写代码来"implement"此功能。

顺便说一句,从你的代码来看,我认为你想在给定的时间间隔内删除特定目录中的文件。看看FileSystemWatcher,watching目录修改时会通知

这绝对是您处理 Control-C 的方式:

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

这个循环会给你 50% cpu 的时间。

像这样的东西可以解决这个问题:

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

应用于您的代码:

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

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

exitEvent.WaitOne();

要使其完成,您必须取消在 CancelKeyPress 事件处理程序中正确启动的任务