System.Linq错误InvalidOperationException:

使用队列来平均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();

我意识到没有提供完整的应用程序就很难说出正在发生什么,但是我应该尝试哪些故障排除步骤呢?

倚天杖
浏览 337回答 1
1回答

一只甜甜圈

(1)发生这种情况,因为您的队列与迭代同时被修改;这是导致队列迭代器抛出的唯一条件InvalidOperationException,或者(2)您的队列没有元素,并且元素类型为不可为空。(1)考虑在此处Queue<T>找到的参考源代码。这是代码中引发异常的地方(第369行):if&nbsp;(_version&nbsp;!=&nbsp;_q._version)&nbsp;ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);_q.version当Queue<T>实例被修改时被更新;实例变量_version的Queue<T>.Enumerator类存储的版本Queue<T>在当你开始迭代的时间。您可以通过在读取和更新周围添加一些锁定或切换为使用来解决此问题ConcurrentQueue<T>。(2)考虑为参考源代码Enumerable<T>发现这里。用于平均值float(第2002行)和float?(第2016行)的代码在处理空集合的方式方面有所不同:可为空的版本返回null,而不可为空的版本则引发异常。您可以通过将队列元素强制转换为float?平均值来解决此问题:float?&nbsp;avPos&nbsp;=&nbsp;_posQueue.Cast<float?>().Average();显然,此更改需要您对null进行检查avPos。
打开App,查看更多内容
随时随地看视频慕课网APP