ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

错误是一个 System.ArgumentOutOfRangeException,提示“索引超出范围”

错误是一个 System.ArgumentOutOfRangeException,提示“索引超出范围” 错误分析根据提供的错误信息ERROR - SetMultiChannelViewData,ex:System.ArgumentOutOfRangeException: 索引超出范围。必须为非负值并小于集合大小。 参数名: index 在 System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 在 System.Collections.Generic.List1.get_Item(Int32 index) 在 CommonCtrlLib.Channel.Add(List1 xList, List1 yList) 位置 D:\SVN\ChengHuangMiao\Branch2_Src\CommonCtrlLib\Oscilloscope\Channel.cs:行号 66 在 CRRCFormat.CRRCFormat.SetMultiChannelViewData(List1 times_src, Object obj2, Oscilloscope oscilloscope) 位置 D:\SVN\ChengHuangMiao\Branch2_Src\ExpandLib\CRRCFormat\CRRCFormat.cs:行号 1150错误是一个 System.ArgumentOutOfRangeException提示“索引超出范围”发生在 CommonCtrlLib.Channel.Add 方法的第66行而该方法被 SetMultiChannelViewData 方法在第1150行调用。问题出现在 Add 方法尝试访问 xList 或 yList 的某个索引时索引超出了列表的范围。错误原因Add 方法的代码如下csharppublic void Add(Listdouble xList, Listdouble yList) { for (int i 0; i xList.Count; i) { XValues.Add(xList[i]); YValues.Add(yList[i]); } }这个方法假设 xList 和 yList 的长度相同并且在循环中通过索引 i 访问两个列表的元素。然而如果 xList 和 yList 的长度不一致例如yList 的长度小于 xList当 i 超出 yList 的范围时就会抛出 ArgumentOutOfRangeException。在 SetMultiChannelViewData 方法中调用 Add 的代码是csharpc.Add(times, lst[J]);这里times 是时间数据列表Listdoublelst[J] 是对应通道的 Y 值数据列表Listdouble。错误表明 times 和 lst[J] 的长度可能不一致导致在 Add 方法中访问 yList即 lst[J]时发生索引越界。可能的具体原因输入数据问题times 和 lst[J] 的长度不匹配。例如times 可能有 100 个元素而 lst[J] 只有 50 个元素。lst[J] 可能为空lst[J].Count 0但代码没有充分检查空列表的情况。times 或 lst[J] 可能未正确初始化或数据在处理过程中被截断。数据处理逻辑问题在 SetMultiChannelViewData 方法中lst 是从 lsobj2 转换来的 SortedDictionaryint, Listdouble复制的。如果 ls 中的某些键对应的 Listdouble 为空或长度与 times 不一致复制到 lst 后仍然会有问题。在循环中lst[J] 的有效性检查不够严格。例如虽然有 if (lst.ContainsKey(J) lst[J].Count 0) 检查但这是在计算 MaxY 和 MinY 时执行的而调用 c.Add(times, lst[J]) 时没有再次验证 lst[J] 的长度是否与 times 匹配。未处理的边界情况如果 times 为空times.Count 0代码会尝试访问 times[times.Count - 1]这也会导致索引越界。如果 oscilloscope.Channels 为空或 lst 不包含某个通道的键可能会导致逻辑中断或未预期的行为。优化方案为了解决这个问题我们需要确保 xList 和 yList 长度一致在调用 Add 方法之前检查 times 和 lst[J] 的长度是否匹配。加强边界检查在访问 times[times.Count - 1] 或其他可能导致索引越界的操作前检查列表是否为空。改进错误处理记录更详细的错误信息以便调试。优化代码结构减少冗余代码增强可读性和健壮性。以下是优化后的 SetMultiChannelViewData 方法代码csharpprivate void SetMultiChannelViewData(Listdouble times_src, object obj2, Oscilloscope oscilloscope) { try { // 输入验证 if (times_src null || times_src.Count 0 || obj2 null || oscilloscope null) { Logger.Error(SetMultiChannelViewData: Invalid input parameters.); return; } Random rd new Random(); string chartType oscilloscope.ChartTitle; Listdouble times new Listdouble(times_src); var ls obj2 as SortedDictionaryint, Listdouble; if (ls null) { Logger.Error(SetMultiChannelViewData: obj2 is not a SortedDictionaryint, Listdouble.); return; } SortedDictionaryint, Listdouble lst new SortedDictionaryint, Listdouble(); Listint posIndexList new Listint(ls.Keys); // 清空现有通道 oscilloscope.ClearAll(); // 如果没有通道则根据数据创建通道 if (oscilloscope.Channels.Count 0) { foreach (int channelIndex in posIndexList) { Color c Color.FromArgb(rd.Next(0, 256), rd.Next(0, 256), rd.Next(0, 256)); oscilloscope.CreateChannel(CommonCtrlLib.DrawingMode.XYLines, , channelIndex.ToString(), c); } } // 复制数据到 lst确保键有效 foreach (int id in ls.Keys) { if (posIndexList.Contains(id) ls[id] ! null ls[id].Count times.Count) { lst.Add(id, new Listdouble(ls[id])); } else { Logger.Warn($SetMultiChannelViewData: Skipped channel {id} due to invalid or mismatched data length.); } } // 如果没有有效数据直接返回 if (lst.Count 0) { Logger.Warn(SetMultiChannelViewData: No valid data to process.); return; } string yUnit ; double t_unit; string unit DataTimeConvertor.AutoConvertByTime(times[times.Count - 1], out t_unit); double maxY double.MinValue; double minY double.MaxValue; // 计算 Y 轴范围 foreach (Channel c in oscilloscope.Channels) { if (!int.TryParse(c.ChannelProps.Legend, out int j)) { Logger.Warn($SetMultiChannelViewData: Invalid channel legend {c.ChannelProps.Legend}.); continue; } if (lst.ContainsKey(j) lst[j].Count 0) { double cacheMaxY lst[j].Max(); double cacheMinY lst[j].Min(); maxY Math.Max(maxY, cacheMaxY); minY Math.Min(minY, cacheMinY); } else { Logger.Warn($SetMultiChannelViewData: No data for channel {j}.); } } // 如果没有有效 Y 数据返回 if (maxY double.MinValue || minY double.MaxValue) { Logger.Warn(SetMultiChannelViewData: No valid Y data to display.); return; } double yScale 1; if (chartType Leakage) { if (RuntimeConfiguration.ICConvert Scientific) { yUnit μA; oscilloscope.FE true; } else { yUnit DataTimeConvertor.AutoConvertByIc(maxY, out double maxYvalue, out double yScaleValue); yScale yScaleValue; oscilloscope.FE false; } } // 更新通道数据 foreach (Channel c in oscilloscope.Channels) { if (!int.TryParse(c.ChannelProps.Legend, out int j)) { Logger.Warn($SetMultiChannelViewData: Invalid channel legend {c.ChannelProps.Legend}.); continue; } if (lst.ContainsKey(j) lst[j].Count times.Count) { c.Clear(); c.ChangeAxisXUnit(t_unit); if (chartType Leakage) { c.ChangeAxisYUnit(yScale); } c.Add(times, lst[j]); c.SetXAxisLimit(times[times.Count - 1], 0, 0); if (oscilloscope.CurrActionDirection ! ActionDirection.None) { // 根据需要处理特定逻辑 } else { c.SetYAxisLimit(1.5 * maxY, minY - (maxY * 0.5), 0); } } else { Logger.Warn($SetMultiChannelViewData: Skipped channel {j} due to missing or mismatched data.); } } // 设置轴标签 if (chartType Leakage) { oscilloscope.YLabel $Leakage[{yUnit}]; } oscilloscope.XLabel $Time[{unit}]; oscilloscope.Refresh(); } catch (Exception ex) { Logger.Error($SetMultiChannelViewData failed: {ex.Message}, StackTrace: {ex.StackTrace}); } }优化点详解输入验证在方法开头检查 times_src、obj2 和 oscilloscope 是否为空或无效。验证 obj2 是否可以正确转换为 SortedDictionaryint, Listdouble。数据长度检查在将数据复制到 lst 时检查 ls[id].Count times.Count确保数据长度一致。在调用 c.Add(times, lst[j]) 之前再次验证 lst[j].Count times.Count。空列表和边界检查在访问 times[times.Count - 1] 之前确认 times 不为空。在计算 maxY 和 minY 时初始化为 double.MinValue 和 double.MaxValue并在没有有效数据时返回。错误日志增强在每个可能失败的步骤中添加详细的日志信息例如跳过无效通道、数据长度不匹配等。捕获异常时记录完整的错误信息和堆栈跟踪。通道索引解析安全使用 int.TryParse 解析 c.ChannelProps.Legend避免无效字符串导致的异常。代码结构优化合并冗余的键检查逻辑PosIndexList 和 ls.Keys 的处理。提前检查和跳过无效数据减少不必要的循环。改进后的 Add 方法为了进一步提高健壮性可以优化 Add 方法添加长度检查csharppublic void Add(Listdouble xList, Listdouble yList) { if (xList null || yList null) { Logger.Error(Channel.Add: xList or yList is null.); return; } if (xList.Count ! yList.Count) { Logger.Error($Channel.Add: Mismatched list lengths (xList: {xList.Count}, yList: {yList.Count}).); return; } for (int i 0; i xList.Count; i) { XValues.Add(xList[i]); YValues.Add(yList[i]); } }这个版本在循环之前检查输入列表是否为空以及长度是否匹配避免索引越界。总结错误原因SetMultiChannelViewData 方法在调用 c.Add(times, lst[J]) 时没有确保 times 和 lst[J] 的长度一致导致 Add 方法中索引越界。优化措施在数据复制和通道更新时严格检查列表长度。增强输入验证和错误日志。优化代码结构提高可读性和健壮性。在 Add 方法中添加长度检查。通过这些改进代码能够更好地处理异常情况避免索引越界错误并提供更清晰的错误信息以便调试。
返回列表