如何在运行时控制线程的CPU利用率?

时间:2014-11-14 13:38:02

标签: c# c++ multithreading cpu-usage

以下代码是我尝试这样做的。但我确实理解这不是一种优雅的方法。有人能指出我正确的方向。任何代码表都是受欢迎的。谢谢你的阅读。

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

}

1 个答案:

答案 0 :(得分:1)

您可以通过创建作业对象来限制流程的CPU数量,您可以通过SetInformationJobObject设置限制。在那里你需要填写结构JOBOBJECT_CPU_RATE_CONTROL_INFORMATION结构。

此功能仅适用于Windows版本> = 8.作为设置硬限制的替代方法,您还可以在超过CPU速率时注册回调。你可以在那里如果您确定它们是CPU活动的主要来源,请暂停您的工作线程。