开发者

Task Parallel Library - I don't understand what I'm doing wrong

开发者 https://www.devze.com 2023-03-03 19:39 出处:网络
This is a two part question. I have a class that gets all processes asynchronously and polls them for CPU usage. Yesterday I had a bug with it and it was solved here.

This is a two part question.

I have a class that gets all processes asynchronously and polls them for CPU usage. Yesterday I had a bug with it and it was solved here.

The first part of the question is why the solution helped. I didn't understand the explanation.

The second part of the question is that I still get an "Object reference not set to an instance of object" exception occasionally when I try to print the result at the end of the process. This is because item.Key is indeed null. I don't understand why that is because I put a breakpoint checking for (开发者_如何学Cprocess == null) and it was never hit. What am I doing wrong?

Code is below.

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


The line

 _usage.Add(process, cpuPercent);

is accessing a not-threadsafe collection from a thread.

Use a ConcurrentDictionary<K,V> instead of the normal dictionary.

The 'null reference' error is just a random symptom, you could get other errors too.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号