-3

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

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

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

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

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

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

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

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

4

2 回答 2

2

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

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只有在条件评估和赋值之间更改了 的值时,才会发生这种情况。

于 2018-07-11T15:06:01.923 回答
0

当然还有另一个线程可以改变_counter检查之间的值

if (_counter > 2)

并将其用于

Values[_counter - 2]

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

var i = _counter - 2;

if (i >= 0)
{
    SeriesCollection[3].Values[i] = double.NaN;
}
于 2018-07-11T16:16:45.930 回答