【问题标题】:Backgroundworker cpu usage后台工作者 cpu 使用率
【发布时间】:2013-03-25 00:25:45
【问题描述】:

我在我的 c# 应用程序 backgroundworker 和 dowork 无限循环中有,但 backgroundworker 的 cpu 使用率非常高 (50%)。如何限制backgroundworker的cpu使用?

代码:

private void ScanWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        while (!worker.CancellationPending)
        {
            Process[] Procesy = Process.GetProcesses();

            foreach (Process Proces in Procesy)
            {

                List<BlaclistedProcess> blacklist = (from p in CurrentBlacklist.Processes
                                                     where p.ProcessName == Proces.ProcessName
                                                     select p).ToList<BlaclistedProcess>();

                if (blacklist.Count == 1)
                {
                    Proces.Kill();
                }
            }
        }
    }

【问题讨论】:

  • 你能显示导致问题的代码吗?
  • 我建议仅根据计时器执行此操作。可能每秒一次或两次......
  • 不要轮询,当process starts 时,让 Windows 告诉你。请牢记这种方法的谬误。如果你有一个黑名单,那么就从一开始就阻止这些程序启动。

标签: c# multithreading backgroundworker cpu cpu-usage


【解决方案1】:

只使用计时器并定期检查这些进程会更容易,无需在另一个线程中执行此操作。

【讨论】:

    【解决方案2】:

    在循环中你可以让后台线程等待一定的时间,例如

    System.Threading.Thread.Sleep(100)
    

    【讨论】:

    • Thread.Sleep 导致线程“正在使用”,等待。当Timer 等资源可用时,线程的最佳用途不是。
    【解决方案3】:

    根据您的代码,您有几个选项。

    我个人会使用Timer 类而不是BackgroundWorker,因为没有必要像现在这样每隔几毫秒进行一次检查。

    避免使用Thread.Sleep() 的另一种方法是使用Thread 类,这样您就可以将其优先级设置为最低或低于正常值。

    【讨论】:

      【解决方案4】:

      使用计时器:

          var timer = new System.Threading.Timer(CheckProcesses);
          timer.Change(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1));
          //...
          timer.Dispose();
      
      private void CheckProcesses(object state)
      {
          Process[] Procesy = Process.GetProcesses();
      
          foreach (Process Proces in Procesy)
          {
      
              List<BlaclistedProcess> blacklist = (from p in CurrentBlacklist.Processes
                                                   where p.ProcessName == Proces.ProcessName
                                                   select p).ToList<BlaclistedProcess>();
      
              if (blacklist.Count == 1)
              {
                  Proces.Kill();
              }
          }
      }
      

      使用计时器,您可以更好地控制执行任务的频率。当计时器没有运行时,没有线程在使用——所以它更具可扩展性。使用Thread.Sleep(),您必须将一个线程用于“等待”——这可能会影响后台工作人员响应取消的速度并使您的 UI 看起来冻结。

      【讨论】:

        【解决方案5】:

        将 Thread.Sleep(...) 添加到 while 循环的末尾。这样在检查进程之间会有一些小的停顿,cpu 使用率会显着下降。

        【讨论】:

        • Thread.Sleep 导致线程“正在使用”,等待。当Timer 等资源可用时,线程的最佳用途不是。
        • 取决于他希望多久检查一次进程。如果他需要每 50 毫秒检查一次,而检查本身需要 100 毫秒,那么计时器会不断重复触发,此时 Thread.Sleep 仍会引入一些暂停。
        • 如果它是恒定的,那么他需要更改周期...Thread.Sleep 不准确。它可能小于你传入的 ms,也可能更少。即您不能使用 Thread.Sleep() 来检查“每 50 毫秒”
        猜你喜欢
        • 2015-10-12
        • 1970-01-01
        • 1970-01-01
        • 2011-07-29
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 2011-03-17
        • 1970-01-01
        相关资源
        最近更新 更多