.net 定时器在For循环中,计数器不递增?

z31licg0  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(164)

对于上下文,我在这里尝试做的是当表单加载时,创建一个具有不同间隔的计时器数组。每个计时器都与表单标签相关联,一旦计时器超时,就会显示表单标签。
我尝试了下面的代码来检查计数器(timerCtr)是否使用消息框递增。10个消息框以正确的间隔弹出,但所有消息框上的值都显示为10。
尝试在for循环中创建断点并单步执行每行代码。timerCtr正确递增,从0开始递增到10,但消息框显示不同的值。
是什么引起的?找了几个小时,还是没找到。

Control[] finalLabelArray = new Control[10];

for (int ctr = 1; ctr < 11; ctr++)
{
    finalLabelArray[ctr] = this.Controls["key" + (ctr).ToString()];
}

System.Timers.Timer[] timerArray = new System.Timers.Timer[finalLabelArray.Length];

for (int timerCtr = 0; timerCtr < timerArray.Length; timerCtr++)
{
    timerArray[timerCtr] = new System.Timers.Timer(timerCtr * 1000 + 1000);
    timerArray[timerCtr].Elapsed += (sender, e) =>
    {
        MessageBox.Show(timerCtr.ToString());
        string labelString = finalLabelArray[timerCtr].Name.ToString();
        int lengthSubstring = labelString.Length - 3;
        int labelNumber = int.Parse(labelString.Substring(3, lengthSubstring));

    };
    timerArray[timerCtr].AutoReset = false;
    timerArray[timerCtr].Start();
}

字符串
还有,有没有更好的方法来实现这一点,而不是使用计时器?
谢谢

vcirk6k6

vcirk6k61#

我怀疑timerCtr.ToString()是在Elapsed被称为-timerCtr的基础上计算的,因此即使在for循环结束后,它仍然存在,最高值为10。你可以改变timerCtr,看看弹出窗口是否也改变了。
对此的最小修复可能是在for循环范围中使用toString()。

for (int timerCtr = 0; timerCtr < timerArray.Length; timerCtr++)
{
    timerArray[timerCtr] = new System.Timers.Timer(timerCtr * 1000 + 1000);

    // string is defined in the for loop instead of Elapsed.
    string toShow = timerCtr.ToString(); 
    string labelName = finalLabelArray[timerCtr].Name.ToString();
    string labelString = labelName;
    int lengthSubstring = labelString.Length - 3;
    int labelNumber = int.Parse(labelString.Substring(3, lengthSubstring));

    timerArray[timerCtr].Elapsed += (sender, e) =>
    {
        MessageBox.Show(toShow);
        // ??? do whatever you want with labelNumber
    };
    timerArray[timerCtr].AutoReset = false;
    timerArray[timerCtr].Start();
}

字符串

相关问题