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

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();
}

これは、「これ」の価値を捉えるために一般的に行われています。

于 2013-05-31T20:03:23.103 に答える