使用队列平均9个浮点值的集合。偶尔(它通常有效!)我收到以下错误
InvalidOperationException:由于当前操作,操作无效 对象的状态System.Linq.Enumerable.Average(IEnumerable`1 源)
违规行是此代码摘录中的最后一行
private bool OnPersonUpdated(IEvent evt)
{
Event_Update castEvent = evt as Event_Update;
if (castEvent != null)
{
if (peopleDict.ContainsKey(castEvent.id))
{
float xVel = castEvent.velX;
GameObject cubeToMove = peopleDict[castEvent.id];
if (xVel > 0)
{
float xPos = -1f * positionForPerson(castEvent.person);
float dif = xPos - _prevX;
if (dif < .5f)
{
_posQueue.Enqueue(xPos);
}
if (_posQueue.Count >= 10)
{
_posQueue.Dequeue();
}
float avPos = _posQueue.Average();
我意识到,如果没有提供完整的应用程序很难分析发生了什么,但我应该尝试哪些故障排除步骤?
答案 0 :(得分:2)
这会发生(1)因为您的队列正在与迭代同时修改;这是导致队列迭代器抛出InvalidOperationException
的唯一条件,或者(2)你的队列没有元素,元素类型是不可为空的。
(1)考虑找到Queue<T>
here的参考源代码。这是抛出异常的代码中的位置(第369行):
if (_version != _q._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
当_q.version
实例被修改时, Queue<T>
会更新; _version
类的实例变量Queue<T>.Enumerator
在您开始迭代时存储Queue<T>
的版本。
您可以通过在读取和更新周围添加一些锁定,或切换为使用ConcurrentQueue<T>
来解决此问题。
(2)考虑Enumerable<T>
找到here的参考源代码。平均float
(第2002行)和float?
(第2016行)的代码在处理空集合的方式上有所不同:可空版本返回null
,而非可空版本则抛出异常。您可以通过在获取平均值之前将队列元素强制转换为float?
来解决此问题:
float? avPos = _posQueue.Cast<float?>().Average();
显然,此更改要求您对avPos
进行无效检查。