本文介绍了并行获取所有进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用 C# 的 TPL 并行获取所有进程的 CPU%.我拥有的代码是:
I'm trying to get the CPU% for all processes in parallel using C#'s TPL. The code that I have is:
private IDictionary<Process, int> _usage = new Dictionary<Process, int>();
public ProcessCpuUsageGetter()
{
Process[] processes = Process.GetProcesses();
int processCount = processes.Count();
Task[] tasks = new Task[processCount];
int counter = 0;
for (int i = 0; i < processCount; i++)
{
tasks[i] = Task.Factory.StartNew(() => DoWork(processes[i]));
}
Task.WaitAll(tasks);
}
private void DoWork(object o)
{
Process process = (Process)o;
PerformanceCounter pc = new PerformanceCounter("Process", "% Processor Time", process.ProcessName, true);
pc.NextValue();
Thread.Sleep(1000);
int cpuPercent = (int)pc.NextValue() / Environment.ProcessorCount;
_usage.Add(process, cpuPercent);
}
但是它失败了 已经添加了具有相同键的项目.
关于我做错了什么的任何想法?
But it fails with An item with the same key has already been added.
Any ideas on what I'm doing wrong?
推荐答案
问题是局部变量i
在传递给启动任务的表达式时closure.这会导致 DoWork(processes[i])
使用 i 的当前值,即使 i
被 for
修改.
The problem is the closure of the local variable i
when passed to the expression for starting the task. This causes current value of i used by the DoWork(processes[i])
even when i
being modified by the for
.
创建局部变量:
for (int i = 0; i < processCount; i++)
{
int localI = i;
tasks[i] = Task.Factory.StartNew(() => DoWork(processes[localI]));
}
这篇关于并行获取所有进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!