【发布时间】:2014-11-14 13:38:01
【问题描述】:
以下代码是我的尝试。但是我确实明白这不是一种优雅的方法。有人可以指出我正确的方向。欢迎任何代码示例。感谢您的阅读。
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;
}
}
【问题讨论】:
-
我不知道能够准确指定您希望应用程序能够使用多少 CPU。我知道您可以设置特定线程的优先级,这将有助于限制进程的 CPU 使用率。关于Threads can be found here 的文档和关于设置Priority can be found here 的文档。我会确保这是您真正想做的事情,并且在这样做之前有一个特定的用例。
-
'Application.DoEvents()' 循环 :((
-
@Cameron 所说的。如果线程正在做有用的工作,为什么要限制它们?如果他们没有做有用的工作,请更改设计,以免他们做无用的工作。如果他们正在做有用的工作,但它是 CPU 密集型的,因此无法接受地降低对 GUI 的响应或影响其他应用程序,请降低线程的优先级,以便它们只吸收其他线程执行后剩余的 CPU。哦 - 摆脱 DoEvents 循环 - 不需要这样的丑陋。替换为 Invoke/BeginInvoke 信号。
-
并且不要设置池线程的优先级。这意味着使用
QueueUserWorkItem、任何Task线程、BackgroundWorker等创建的线程。如果您需要设置优先级,则创建和管理您自己的线程(即Thread类)。 -
@JimMischel - 如果设置池头的优先级(应该有 AfterCreation() 事件或一些覆盖 ctor 的虚拟方法),要么不切实际,要么不推荐,池设计者需要一记耳光:)
标签: c# c++ multithreading cpu-usage