2014-11-14 46 views
0

以下代碼是我的嘗試。但我明白這不是一個優雅的方法。有人能指出我的方向是正確的嗎?任何代碼是受歡迎的。謝謝你的閱讀。如何在運行時控制線程的CPU利用率?

snap shot of application

public partial class Form1 : Form 
{ 
    BackgroundWorker worker = new BackgroundWorker(); 
    delegate void SetTextCallback(string text); 

    public Form1() 
    { 
     InitializeComponent(); 
     worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork); 
     worker.ProgressChanged += worker_ProgressChanged; 
     worker.WorkerReportsProgress = true; 
     worker.WorkerSupportsCancellation = true; 
     worker.RunWorkerAsync(Convert.ToInt32(numericUpDown_CPU.Value)); 
    } 

    void worker_ProgressChanged(Object sender, ProgressChangedEventArgs e) 
    { 
     double currentUtilization = (double)e.UserState; 
     this.BeginInvoke(new SetTextCallback(SetText), new object[] { currentUtilization.ToString() }); 
     textBoxCurrentUtilization.Text = currentUtilization.ToString(); 
    } 

    void worker_DoWork(Object sender, DoWorkEventArgs e) 
    { 
     int CPU_utilization = (int)e.Argument; 

     while (true) 
     { 
      if (worker.CancellationPending) 
       return; 

      Thread.Sleep(CPU_utilization); 
      int total = 0; 
      Process p = Process.GetCurrentProcess(); 
      foreach (ProcessThread pt in p.Threads) 
      { 
       total += pt.TotalProcessorTime.Milliseconds; 
       if (pt.Id == (int)AppDomain.GetCurrentThreadId()) 
       { 
        TimeSpan ts = pt.TotalProcessorTime; 
        double percentage = ((double)(ts.Milliseconds + 1)/total) * 100; 
        worker.ReportProgress(Convert.ToInt32(percentage), percentage); 
       } 
      } 
     } 
    } 

    private void numericUpDown_CPU_ValueChanged(object sender, EventArgs e) 
    { 
     worker.CancelAsync(); 

     while (worker.IsBusy) 
      Thread.Sleep(100); 

     int desiredUtilization = Math.Abs(Convert.ToInt32(100 - numericUpDown_CPU.Value)); 
     worker.RunWorkerAsync(desiredUtilization); //restart worker 
    } 

    void SetText(string text) 
    { 
     this.textBoxCurrentUtilization.Text = text; 
    } 

} 
+0

我不知道能夠確切指定您的應用程序能夠使用多少CPU。我知道你可以設置一個特定線程的優先級,這將有助於節制進程的CPU使用率。關於[線程的文檔可以在這裏找到](http://msdn.microsoft.com/en-us/library/system.threading.thread(v = vs.110).aspx)以及關於設置[Priority可以是在這裏找到](http://msdn.microsoft.com/en-us/library/system.threading.thread.priority(v = vs.110).aspx)。我會確保這是你真正想做的事情,並且在這之前有一個特定的用例。 – Cameron 2014-11-14 13:51:02

+1

'Application.DoEvents()'循環:(( – 2014-11-14 14:25:52

+3

@Cameron說了什麼,如果線程正在做有用的工作,爲什麼要試着扼殺它們?如果他們沒有做有用的工作,改變設計,如果他們正在做有用的工作,但這是CPU密集型的,並且如此不可接受地降低了對GUI的響應或影響其他應用程序,那麼降低線程的優先級,以便它們只會吸收其他線程之後留下的CPU已經執行了哦 - 並且擺脫了DoEvents循環 - 不需要這樣的醜陋,用Invoke/BeginInvoke信號代替 – 2014-11-14 14:32:08

回答

1

您可以通過創建一個作業對象,您可以設置通過SetInformationJobObject限制限制CPU的數量爲你的過程。你需要填寫結構JOBOBJECT_CPU_RATE_CONTROL_INFORMATION結構。

此功能僅在Windows版本> = 8上可用。作爲設置硬限制的替代方法,您還可以在CPU速率超出時註冊回調。你可以例如如果您確定它們是CPU活動的主要來源,請暫停您的工作線程。