'System.ArgumentOutOfRangeException' 的 C# 奇怪实例
C# Strange Instance of 'System.ArgumentOutOfRangeException'
我正在使用 LineSeries 从 Beto Rodriguez 的库 LiveCharts.Wpf 中绘制图表。我将值发送到它绘制并相应更新的图表。
我有一个 SeriesCollection,我根据计数器添加值并删除一些值,例如:
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
因此,如果计数器等于大于 2 的值,我将值设置为 NaN,即我从图表中删除一个点。
问题是,在随机时间,我得到一个 System.ArgumentOutOfRangeException
,上面写着
Index was out of range. Must be non-negative and less than the size of the collection.
在值被设置为 NaN
且调试器显示计数器等于 0
.
的位置
显然我不允许在这个 if (_counter > 2 )
条件下当计数器等于或小于 2 时执行此代码,那么这个异常怎么会发生在这个特定点?
编辑:这个问题不是关于 'System.ArgumentOutOfRangeException' 是什么,正如重复问题中所指出的那样,而是关于尽管事先检查过但为什么会发生此错误。基本上,由于多线程,_counter 的值被设置为代码中其他地方的意外值,这是主要问题。 SeriesCollection[3] 与异常无关,如果有人这么认为,我建议从 LiveCharts 库本身检查这种数据类型的实际含义。
此代码在以下情况下抛出索引超出范围异常:
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
SeriesCollection
中的项目少于 4 个。
SeriesCollection[3].Values
中的项目少于 _counter-1
项。 (因此,如果计数器为 3,则 Values
集合必须至少有两个值 - 因此 _counter-2
将是第二项。
另外,如果这是一个多线程环境,很可能不同的线程在条件和赋值之间更改了 _counter
的值。为防止这种情况,您需要使用 locks:
private object _lock = new Object();
lock(_lock)
{
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
}
请注意,您的问题确实建议在多线程环境中工作 -
at the point where the value is being set to NaN and the debugger shows that the counter is equal to 0.
只有在 _counter
的值在条件评估和赋值之间发生更改时才会发生这种情况。
肯定有另一个线程在检查
之间更改了_counter
的值
if (_counter > 2)
并在
中使用它
Values[_counter - 2]
更安全的实现方式是只访问一次:
var i = _counter - 2;
if (i >= 0)
{
SeriesCollection[3].Values[i] = double.NaN;
}
我正在使用 LineSeries 从 Beto Rodriguez 的库 LiveCharts.Wpf 中绘制图表。我将值发送到它绘制并相应更新的图表。 我有一个 SeriesCollection,我根据计数器添加值并删除一些值,例如:
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
因此,如果计数器等于大于 2 的值,我将值设置为 NaN,即我从图表中删除一个点。
问题是,在随机时间,我得到一个 System.ArgumentOutOfRangeException
,上面写着
Index was out of range. Must be non-negative and less than the size of the collection.
在值被设置为 NaN
且调试器显示计数器等于 0
.
显然我不允许在这个 if (_counter > 2 )
条件下当计数器等于或小于 2 时执行此代码,那么这个异常怎么会发生在这个特定点?
编辑:这个问题不是关于 'System.ArgumentOutOfRangeException' 是什么,正如重复问题中所指出的那样,而是关于尽管事先检查过但为什么会发生此错误。基本上,由于多线程,_counter 的值被设置为代码中其他地方的意外值,这是主要问题。 SeriesCollection[3] 与异常无关,如果有人这么认为,我建议从 LiveCharts 库本身检查这种数据类型的实际含义。
此代码在以下情况下抛出索引超出范围异常:
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
SeriesCollection
中的项目少于 4 个。SeriesCollection[3].Values
中的项目少于_counter-1
项。 (因此,如果计数器为 3,则Values
集合必须至少有两个值 - 因此_counter-2
将是第二项。
另外,如果这是一个多线程环境,很可能不同的线程在条件和赋值之间更改了 _counter
的值。为防止这种情况,您需要使用 locks:
private object _lock = new Object();
lock(_lock)
{
if (_counter > 2 )
{
SeriesCollection[3].Values[_counter-2] = double.NaN;
}
}
请注意,您的问题确实建议在多线程环境中工作 -
at the point where the value is being set to NaN and the debugger shows that the counter is equal to 0.
只有在 _counter
的值在条件评估和赋值之间发生更改时才会发生这种情况。
肯定有另一个线程在检查
之间更改了_counter
的值
if (_counter > 2)
并在
中使用它Values[_counter - 2]
更安全的实现方式是只访问一次:
var i = _counter - 2;
if (i >= 0)
{
SeriesCollection[3].Values[i] = double.NaN;
}