【问题标题】:Task Parallel Library - I don't understand what I'm doing wrong任务并行库 - 我不明白我做错了什么
【发布时间】:2011-05-07 17:15:50
【问题描述】:

这是一个两部分的问题。
我有一个类可以异步获取所有进程并轮询它们的 CPU 使用率。昨天我遇到了一个错误,它已解决here
问题的第一部分是为什么解决方案有帮助。我没看懂解释。
问题的第二部分是,当我尝试在进程结束时打印结果时,偶尔仍会收到 "Object reference not set to an instance of object" 异常。这是因为item.Key 确实为空。我不明白为什么会这样,因为我为(process == null) 设置了一个断点检查,但它从未被命中。我究竟做错了什么?
代码如下。

class ProcessCpuUsageGetter
    {
        private IDictionary<Process, int> _usage;

        public IDictionary<Process, int> Usage { get { return _usage; } }

        public ProcessCpuUsageGetter()
        {
            while (true)
            {
                Process[] processes = Process.GetProcesses();
                int processCount = processes.Count();
                Task[] tasks = new Task[processCount];

                _usage = new Dictionary<Process, int>();
                for (int i = 0; i < processCount; i++)
                {
                    var localI = i;
                    var localProcess = processes[localI];
                    tasks[localI] = Task.Factory.StartNew(() => DoWork(localProcess));
                }
                Task.WaitAll(tasks);

                foreach (var item in Usage)
                {
                    Console.WriteLine("{0} - {1}%", item.Key.ProcessName, item.Value);
                }                
            }
        }

        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;
            if (process == null)
            {
                var x = 5;
            }
            if (_usage == null)
            {
                var t = 6;
            }
            _usage.Add(process, cpuPercent);
        }
    }

【问题讨论】:

  • “问题的第一部分是为什么解决方案有帮助” - 然后请在该问题/答案下的评论中提出。
  • 只是出于好奇,为什么DoWork 采用object 参数只是为了立即将其转换为Process
  • @Henk - 已经在 cmets 下询问过,但没有得到回复。
  • @Matti - 剩余代码,我应该更改它。
  • 使用单词(捕获)进行查找。这是一个非常常见的错误。

标签: c# asynchronous task-parallel-library


【解决方案1】:

线

 _usage.Add(process, cpuPercent);

正在从一个线程访问一个非线程安全的集合。

使用ConcurrentDictionary&lt;K,V&gt; 代替普通字典。

“空引用”错误只是一种随机症状,您也可能会遇到其他错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-11
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多