为了账号安全,请及时绑定邮箱和手机立即绑定

System.Linq错误InvalidOperationException:

System.Linq错误InvalidOperationException:

C#
倚天杖 2021-05-11 17:26:34
使用队列来平均9个float值的集合。有时(通常可以正常工作!),我收到以下错误InvalidOperationException:操作由于对象System.Linq.Enumerable.Average(IEnumerable`1 source)的当前状态而无效令人反感的行是此代码摘录中的最后一行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();我意识到没有提供完整的应用程序就很难说出正在发生什么,但是我应该尝试哪些故障排除步骤呢?
查看完整描述

1 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

(1)发生这种情况,因为您的队列与迭代同时被修改;这是导致队列迭代器抛出的唯一条件InvalidOperationException,或者(2)您的队列没有元素,并且元素类型为不可为空。

(1)考虑在此处Queue<T>找到的参考源代码。这是代码中引发异常的地方(第369行):

if (_version != _q._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);

_q.versionQueue<T>实例被修改时被更新;实例变量_versionQueue<T>.Enumerator类存储的版本Queue<T>在当你开始迭代的时间。

您可以通过在读取和更新周围添加一些锁定或切换为使用来解决此问题ConcurrentQueue<T>

(2)考虑为参考源代码Enumerable<T>发现这里。用于平均值float(第2002行)和float?(第2016行)的代码在处理空集合的方式方面有所不同:可为空的版本返回null,而不可为空的版本则引发异常。您可以通过将队列元素强制转换为float?平均值来解决此问题:

float? avPos = _posQueue.Cast<float?>().Average();

显然,此更改需要您对null进行检查avPos


查看完整回答
反对 回复 2021-05-23
  • 1 回答
  • 0 关注
  • 336 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信