Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么有时我会得到异常索引?_C#_.net_Winforms - Fatal编程技术网

C# 为什么有时我会得到异常索引?

C# 为什么有时我会得到异常索引?,c#,.net,winforms,C#,.net,Winforms,这是一个计时器滴答事件,我正在获取每个进程的内存使用情况。 在95%的时间里,甚至更多的时候,它工作得很好。我试了20次运行我的程序,直到异常抛出 在表格顶部: System.Timers.Timer aTimer = new System.Timers.Timer(); 然后在构造函数中: aTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent); aTimer.Interval = 1000; 然后,计时器

这是一个计时器滴答事件,我正在获取每个进程的内存使用情况。 在95%的时间里,甚至更多的时候,它工作得很好。我试了20次运行我的程序,直到异常抛出

在表格顶部:

System.Timers.Timer aTimer = new System.Timers.Timer();
然后在构造函数中:

aTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000;
然后,计时器已过事件:

Image ima = null;
        private void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            List<MyProgress> prog = new List<MyProgress>();

            prog = new List<MyProgress>();
            DoubleBufferedd(dataGridView1, true);
            procList = Process.GetProcesses().ToList();
            for (int i = 0; i < procList.Count; i++)
            {
                Process[] processes = Process.GetProcessesByName(procList[i].ProcessName);
                PerformanceCounter performanceCounter = new PerformanceCounter();
                performanceCounter.CategoryName = "Process";
                performanceCounter.CounterName = "Working Set - Private";
                performanceCounter.InstanceName = processes[0].ProcessName;
                try
                {
                    var icon = Icon.ExtractAssociatedIcon(processes[0].MainModule.FileName);
                    ima = icon.ToBitmap();
                    ima = resizeImage(ima, new Size(25, 25));
                    ima = (Image)(new Bitmap(ima, new Size(25, 25)));
                }
                catch
                {

                }
                prog.Add(new MyProgress { Id = procList[i].Id, Progress = ((uint)performanceCounter.NextValue() / 1024).ToString("N0"), ProcImage = ima, ProcessName = procList[i].ProcessName });


            }
            BeginInvoke((Action)(() =>
            {
            List<MyProgress> list = prog;//new List<MyProgress>();



                foreach (MyProgress p in list)
                {
                    DataGridViewRow row;

                    if (!processRows.TryGetValue(p.Id, out row))
                    {
                        int index = dataGridView1.Rows.Add(p.ProcImage, p.ProcessName, null, p.Progress);
                        row = dataGridView1.Rows[index];
                        processRows.Add(p.Id, row);
                    }
                    else
                    {
                        row.Cells[3].Value = p.Progress;
                    }
                }
                foreach (int id in processRows.Keys.Except(list.Select(p => p.Id)).ToArray())
                {
                    dataGridView1.Rows.Remove(processRows[id]);
                    processRows.Remove(id);
                }
            }));
        }
中发生“System.IndexOutOfRangeException”类型的异常 Automation.exe,但未在用户代码中处理

附加信息:索引超出了数组的边界

用户代码未处理System.IndexOutOfRangeException

它只会发生一次或多次。大多数情况下,异常未显示

当我将鼠标放在proclist上时,我看到计数:

Count=函数计算已禁用,因为上一个函数 评估超时。必须继续执行才能重新启用函数 评估

计时器的间隔设置为1000ms

不确定这意味着什么,我必须继续执行以重新启用函数求值。以及如何修复它。 为什么有时候它会做出例外,而在大多数情况下不会

我根据Dan answer更改了代码,但现在在另一个地方出现异常。 这是新代码:

Image ima = null;
        private void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
        {
            List<MyProgress> prog = new List<MyProgress>();

            prog = new List<MyProgress>();
            DoubleBufferedd(dataGridView1, true);
            procList = Process.GetProcesses().ToList();
            for (int i = 0; i < procList.Count; i++)
            {
                                PerformanceCounter performanceCounter = new PerformanceCounter();
                performanceCounter.CategoryName = "Process";
                performanceCounter.CounterName = "Working Set - Private";//"Working Set";
                performanceCounter.InstanceName = procList[i].ProcessName;
                try
                {
                    var icon = Icon.ExtractAssociatedIcon(procList[i].MainModule.FileName);
                    ima = icon.ToBitmap();
                    ima = resizeImage(ima, new Size(25, 25));
                    ima = (Image)(new Bitmap(ima, new Size(25, 25)));
                }
                catch
                {

                }
                prog.Add(new MyProgress { Id = procList[i].Id, Progress = ((uint)performanceCounter.NextValue() / 1024).ToString("N0"), ProcImage = ima, ProcessName = procList[i].ProcessName });


            }
            BeginInvoke((Action)(() =>
            {
            List<MyProgress> list = prog;



                foreach (MyProgress p in list)
                {
                    DataGridViewRow row;

                    if (!processRows.TryGetValue(p.Id, out row))
                    {
                                                int index = dataGridView1.Rows.Add(p.ProcImage, p.ProcessName, null, p.Progress);
                        row = dataGridView1.Rows[index];
                        processRows.Add(p.Id, row);
                    }
                    else
                    {
                        row.Cells[3].Value = p.Progress;
                    }
                }
                foreach (int id in processRows.Keys.Except(list.Select(p => p.Id)).ToArray())
                {
                    dataGridView1.Rows.Remove(processRows[id]);
                    processRows.Remove(id);
                }
            }));
        }
这一行我也在使用procList[i]

performanceCounter.InstanceName = procList[i].ProcessName;
var icon = Icon.ExtractAssociatedIcon(procList[i].MainModule.FileName);
但现在我在网上遇到了一个例外:

 performanceCounter.InstanceName = processes[0].ProcessName;
prog.Add(new MyProgress { Id = procList[i].Id, Progress = ((uint)performanceCounter.NextValue() / 1024).ToString("N0"), ProcImage = ima, ProcessName = procList[i].ProcessName });
无效操作例外

System.dll中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理

其他信息:指定类别中不存在实例“SearchFilterHost”

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=Instance 'SearchFilterHost' does not exist in the specified Category.
  Source=System
  StackTrace:
       at System.Diagnostics.CounterDefinitionSample.GetInstanceValue(String instanceName)
       at System.Diagnostics.PerformanceCounter.NextSample()
       at System.Diagnostics.PerformanceCounter.NextValue()
       at Automation.Form1.OnTimedEvent(Object source, ElapsedEventArgs e) in d:\C-Sharp\Automation\Automation\Automation\Form1.cs:line 805
       at System.Timers.Timer.MyTimerCallback(Object state)
  InnerException: 

可能没有具有您要查找的名称的进程。当这种情况发生时,进程的长度将为0,并且没有有效的索引。所以,无论你在括号里放了什么数字,你都会得到一个IndexOutOfRangeException

要解决此问题,在使用进程数组之前,应确保存在匹配的进程:


实现这一目标还有很多其他方法,但这应该为您指明正确的方向。

以下是与您的问题相关的三行重要代码:

procList = Process.GetProcesses().ToList();
Process[] processes = Process.GetProcessesByName(procList[i].ProcessName);
performanceCounter.InstanceName = processes[0].ProcessName;
你在这里做的是

获取所有进程的列表 获取与第一个列表中的一个进程同名的进程列表 获取第二个列表中第一个进程的名称 忽略这里的冗余,问题在于时间

假设您有一个正在运行的进程foo.exe。该过程出现在步骤1的列表中。如果该过程在步骤1和步骤2之间终止,则步骤2中foo.exe的列表将为空。当列表为空时调用进程[0]将引发您看到的异常


为了避免这种情况,我建议您完全避免第2步:您已经检索了所有进程的信息,所以请使用您已经拥有的数据。这将有可能加快您的代码的好处

在循环过程中,如果进程结束,将引发异常…

您可能遇到线程问题。您可以使用来更好地了解发生了什么。GetProcessByName可能返回空数组,索引0超出范围。不要假设进程[0]存在,您将不会获得异常。当您超出数组的边界时,会发生IndexOutOfRangeException。例如,如果您有一个包含3个对象的数组,并且尝试调用ArrayName[4],则会出现该错误。设置断点并找出代码不工作的原因。数组是否已满?不,那么它将超出数组的边界。Dan我更改了代码,删除了第2步中的Process[]processs行,现在不使用它。接下来的两行中,instancename=I did procList[I].ProcessName的行和extract procList[I]图标的行.MainModule.FileName但现在我遇到了另一个异常。Dan我也用我所做的更改和现在遇到的异常更新了我的问题。@ManuelSpechia:您的更新更改了问题的含义/内容,使现有答案不再相关。您应该恢复编辑以保留现有问题,然后将新问题作为单独问题发布。不过,作为解决新问题的建议:打破这条界线。您正在调用多个方法,但不清楚是哪个方法引发了异常,因此使用额外的局部变量在单独的行上调用每个方法来存储结果,您可以缩小问题的范围。
procList = Process.GetProcesses().ToList();
Process[] processes = Process.GetProcessesByName(procList[i].ProcessName);
performanceCounter.InstanceName = processes[0].ProcessName;