C# 奇怪的实例 'System.ArgumentOutOfRangeException'



我正在使用LineSeries从Beto Rodriguez的LiveCharts.Wpf库中绘制图表。我正在将值发送到它绘制并相应地更新的图表。 我有一个 SeriesCollection,我根据计数器向其添加值并删除一些值,例如:

if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;   
}

因此,如果计数器等于大于 2 ,我将值设置为 NaN,即从图表中删除一个点。

问题是,在随机时间,我得到一个System.ArgumentOutOfRangeException,它说

指数超出范围。必须是非负数且小于集合的大小。

在将值设置为NaN并且调试器显示计数器等于0的点。

显然,当计数器在此if (_counter > 2 )条件下等于或小于 2 时,我不允许执行此代码,那么在这个特定点上怎么会发生这种异常呢?

编辑:这个问题不是关于什么是"System.ArgumentOutOfRangeException",正如重复问题中指出的那样,而是关于尽管提前检查了错误,但为什么会发生此错误。基本上,由于多线程,_counter的值在代码中的其他地方被设置为意外值,这是主要问题。SeriesCollection[3] 与异常无关,如果有人这么认为,我建议从 LiveCharts 库本身查看这种数据类型的实际含义。

此代码在以下情况下会引发索引超出范围异常:

if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;   
}
  1. SeriesCollection中的项目少于 4 个。

  2. SeriesCollection[3].Values中的项目少于_counter-1个。(因此,如果计数器为 3,则Values集合必须至少有两个值 - 以便_counter-2将成为第二项。

此外,如果这是一个多线程环境,则很可能是不同的线程更改了条件和赋值之间的_counter值。为了防止这种情况,您需要使用锁:

private object _lock = new Object(); 
lock(_lock)
{
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;   
}
}

请注意,您的问题确实建议在多线程环境中工作 -

在值设置为 NaN 且调试器显示计数器等于 0 的位置。

仅当在条件评估和分配之间更改了_counter的值时,才会发生这种情况。

当然还有另一个线程在检查之间更改_counter的值

if (_counter > 2)

并在

Values[_counter - 2]

更安全的实现只会访问它一次:

var i = _counter - 2;
if (i >= 0)
{
SeriesCollection[3].Values[i] = double.NaN;
}

相关内容

  • 没有找到相关文章