简体   繁体   中英

How to control the CPU utilization of a thread at runtime?

The following code is my attempt to do that. However i do understand this is not an elegant approach. Could someone point me in the right direction. Any code-sampe is welcome. Thank you for reading.

应用快照

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

}

You can limit the amount of CPU for your process by creating a job object where you can set the limits via SetInformationJobObject. There you need to fill out the structure JOBOBJECT_CPU_RATE_CONTROL_INFORMATION structure.

This feature is only available on Windows versions >= 8. As an alternative to setting a hard limit you can also register a callback when the CPU rate is exceeded. There you could eg pause your worker threads if you are sure that they are the main source of CPU activity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM