2014-11-14 4 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) 및 [우선 순위는 다음과 같을 수 있습니다. (http://msdn.microsoft.com/en-us/library/system.threading.thread.priority (v = vs.110) .aspx)를 참조하십시오. 나는 이것이 당신이 정말로하고 싶은 일이고, 그렇게하기 전에 특정한 유스 케이스를 가지고 있는지 확인하고자한다. – Cameron

+1

'Application.DoEvents()'loop : (( –

+3

) @Cameron이 말한 것 유용한 작업을 수행하는 스레드가 왜 스로틀을 시도합니까? 유용한 작업을 수행하지 않는 경우 디자인을 변경하여 ' 유용한 일을하고 있지만 CPU 사용량이 많아서 GUI에 대한 응답을 부적절하게 낮추거나 다른 응용 프로그램에 영향을주는 경우 스레드의 우선 순위를 낮추어 다른 스레드 다음에 남아있는 CPU 만 흡수하도록합니다 오 - DoEvents 루프를 제거하십시오 - 그런 추함이 필요 없습니다 Invoke/BeginInvoke 시그널링으로 대체하십시오 –

답변

1

당신은 당신이 SetInformationJobObject을 통해 제한을 설정할 수 있습니다 작업 개체를 생성하여 프로세스에 대한 CPU의 양을 제한 할 수 있습니다. 거기 구조 JOBOBJECT_CPU_RATE_CONTROL_INFORMATION 구조를 작성해야합니다.

이 기능은 Windows 버전 8 이상에서만 사용할 수 있습니다. 하드 제한을 설정하는 대신 CPU 속도가 초과되면 콜백을 등록 할 수도 있습니다. 예를 들어 작업자 스레드가 CPU 활동의 주요 소스라고 확신 할 경우 작업자 스레드를 일시 중지하십시오.

관련 문제