1
if (Int32.Parse(strTotals) == 0 && nTotalCount != 0)
{
    nTotalCount = 0;
    for (int j = 0; j < 66; j++)
    {
        if (GameHistoryPicBox1[j].InvokeRequired)
        {
            GameHistoryPicBox1[j].BeginInvoke(new MethodInvoker(() =>
            {
                if ((j + j / 6) % 2 == 0)
                    GameHistoryPicBox1[j].Image = Properties.Resources.al1;  // Line2
                else
                    GameHistoryPicBox1[j].Image = Properties.Resources.al2;  // Line4
            }));
        }
        else
        {
            if ((j + j / 6) % 2 == 0)
                GameHistoryPicBox1[j].Image = Properties.Resources.al1;
            else
                GameHistoryPicBox1[j].Image = Properties.Resources.al2;
        }
    }
}

我一直在nTotalCount使用线程检查值。

如果nTotalCount为零,那么我必须清理所有游戏图片框图像。

所以我实现了上面的代码。

不幸的是,我得到了错误:

“System.IndexOutOfRangeException”类型的未处理异常

在 2 号线和 4 号线。

并且j价值是66

这个j值有可能66吗?

4

3 回答 3

2

变量j被传递到闭包中,由于调用是异步的,它实际上是在循环完成后的某个时间点执行的。您无法确定j执行委托时的值是多少。

尝试将jin 的值作为参数传递给委托,如下所示:

GameHistoryPicBox1[j].BeginInvoke(new Action<int>((x) =>
{
    if ((x + x / 6) % 2 == 0)
        GameHistoryPicBox1[x].Image = Properties.Resources.al1;
    else
        GameHistoryPicBox1[x].Image = Properties.Resources.al2;
}), j);
于 2013-10-31T16:42:06.847 回答
2

这是因为闭包的工作方式。您正在创建并通过引用传递给MethodInvoker引用j变量的 lambda 表达式。因此,当这段代码正在执行时(几乎可以在任何时候,因为它是异步的),j变量可以具有从0to的任何值66。它可以66在循环完成之后。

一个快速的解决方法是复制j

int index = j;
GameHistoryPicBox1[index].BeginInvoke(new MethodInvoker(() =>
    {
        if ((index + index / 6) % 2 == 0)
            GameHistoryPicBox1[index].Image = Properties.Resources.al1;  // Line2
        else
            GameHistoryPicBox1[index].Image = Properties.Resources.al2;  // Line4
    }));

您可以在此处阅读有关此内容的更多信息。

于 2013-10-31T16:42:30.990 回答
2

你被闭包中的循环变量所困扰。

代替

for (int j = 0; j < 66; j++)
{
    //blahblahblah
}

for (int jj = 0; jj < 66; jj++)
{
    int j = jj;
    //blahblahblah
}
于 2013-10-31T16:44:22.187 回答