导致IndexOutOfRangeException的计时器

时间:2014-10-17 01:55:10

标签: c# exception timer indexing xna

我有一些类似下面代码的代码。它有点复杂,但基本上在我的游戏中看似随机的时间我得到IndexOutOfRange例外。

当我阅读更多细节时,它说参数“index”出现异常(我没有一个名字,所以我认为它可能来自List<Rectangle>)。

void Update()
{
    CurrentIndex++
    if(CurrentIndex > EndFrame)
    {
        CurrentIndex = StartFrame;
    }
}

public override Rectangle GetSize(Vector2 position)
{
    //Exception occurs here
    return new Rectangle(
        (int)(position.X + MaxCharacterSize.X - AnimationList[CurrentFrame].BoundingBox.Width),
        (int)(position.Y + MaxCharacterSize.Y - AnimationList[CurrentFrame].BoundingBox.Height),
        AnimationList[CurrentFrame].BoundingBox.Width,
        AnimationList[CurrentFrame].BoundingBox.Height);
}

为什么会抛出异常?甚至很难调试,因为它似乎是随机发生的。是Update()仅由Timer.Elapsed事件调用的事实?

我将永远感谢能够回答它的人。

2 个答案:

答案 0 :(得分:3)

没有好的代码示例很难说。但是,很可能您的Timer.Elapsed事件是在处理GUI的线程之外的线程上引发的。所以你有一个竞争条件,定时器可以递增索引,但是在该线程暂时挂起并且你的GUI线程试图使用(现在无效)索引之前还没有包装它。

解决问题的一种方法:

void Update()
{
    int newIndex = CurrentIndex + 1;
    if(newIndex > EndFrame)
    {
        newIndex = StartFrame;
    }
    CurrentIndex = newIndex;
}

现在所有这一切,(再次)没有更好的代码示例,我们无法看到您可能拥有的其他线程错误。以上假设CurrentIndex是“易变的”,并且当其他线程正在运行时,EndFrame和StartFrame不会改变。

答案 1 :(得分:1)

例外是因为CurrentIndex的值超出了AnimationList列表的末尾。

如果没有完整的代码,很难说,但我要看的两件事是:

  1. 确保EndFrame不是一个一个(即确保它没有初始化为AnimationList的 length ,因为如果它是AnimationList [EndFrame]无效并将抛出该异常)

  2. 确保Update()例程不能在GetSize()方法的其他线程中触发。如果是(并且必须是),则需要进行一些同步以防止在GetSize()递增到达到列表末尾的检查之间调用CurrentIndex。< / p>