2

我想要一段测试代码,它创建一个任务集合,然后在不久的将来某个随机时间用每个任务的索引调用一个方法。

我是这样写的:

Random rnd = new Random();

for (Int32 taskIndex = 0; taskIndex < 10; taskIndex++)
{
    _tasks.Add(String.Format("Task_{0}", taskIndex));
    Progress.AddItem(_tasks[taskIndex]);

    Int32 timeDelay = 5 + rnd.Next(10);

    DispatcherTimer dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Interval = TimeSpan.FromSeconds(timeDelay);
    dispatcherTimer.Tick += (sndr, eArgs) =>
    {
        dispatcherTimer.Stop();
        Progress.SetItemStatus(taskIndex, Status.Executing);
    };
    dispatcherTimer.Start();
}

当它运行时,它总是将 10 作为 taskIndex 传递给 Progress.SetItemStatus()。我理解为什么会这样(谢谢,Skeet 先生)——因为 taskIndex 是在匿名方法中捕获的,并在方法执行时使用它的值。

我想知道的是实现我的目标的最优雅的方式,即在设置 Tick 事件时传递实例中的值。

4

2 回答 2

3

您正在关闭循环变量。有关详细信息,请参阅Eric Lippert 的博客文章。

基本上,延迟执行使用的是 taskIndex,它在执行时将始终为 10(或任何最后一个值)。

Random rnd = new Random();

for (Int32 taskIndex = 0; taskIndex < 10; taskIndex++)
{
    Int32 tempIndex = taskIndex;
    _tasks.Add(String.Format("Task_{0}", tempIndex));
    Progress.AddItem(_tasks[tempIndex]);

    Int32 timeDelay = 5 + rnd.Next(10);

    DispatcherTimer dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Interval = TimeSpan.FromSeconds(timeDelay);
    dispatcherTimer.Tick += (sndr, eArgs) =>
    {
        dispatcherTimer.Stop();
        Progress.SetItemStatus(tempIndex, Status.Executing);
    };
    dispatcherTimer.Start();
}
于 2013-05-31T19:25:26.447 回答
0

我只是在这里猜测(还没有真正测试过),如果您在 for 循环代码中分配一个本地值,该值应该捕获迭代的值。

Random rnd = new Random();

for (Int32 taskIdx = 0; taskIdx < 10; taskIdx++)
{
    var taskIndex = taskIdx;
    _tasks.Add(String.Format("Task_{0}", taskIndex));
    Progress.AddItem(_tasks[taskIndex]);

    Int32 timeDelay = 5 + rnd.Next(10);

    DispatcherTimer dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Interval = TimeSpan.FromSeconds(timeDelay);
    dispatcherTimer.Tick += (sndr, eArgs) =>
    {
        dispatcherTimer.Stop();
        Progress.SetItemStatus(taskIndex, Status.Executing);
    };
    dispatcherTimer.Start();
}

这是为了捕捉“this”的价值而共同完成的。

于 2013-05-31T20:03:23.103 回答