Search code examples
c#timer

c# Timer in a for loop is not working as expected


I am quite new to c# and recently met a problem when I want to execute an Action of each item in an array, with incremental seconds, like below

DelayAction(1000, new Action(() => { Instance_OnATSSSignalEvent(List[1]); }));
DelayAction(2000, new Action(() => { Instance_OnATSSSignalEvent(List[2]); }));
DelayAction(3000, new Action(() => { Instance_OnATSSSignalEvent(List[3]); }));
DelayAction(4000, new Action(() => { Instance_OnATSSSignalEvent(List[4]); }));
DelayAction(5000, new Action(() => { Instance_OnATSSSignalEvent(List[5]); }));
 public static void DelayAction(int millisecond, Action action)
        {
            var timer = new DispatcherTimer();
            timer.Tick += delegate
            {
                action.Invoke();
                timer.Stop();
            };

            timer.Interval = TimeSpan.FromMilliseconds(millisecond);
            timer.Start();
        }

The above line-by-line method works, and I can see UI updated every second. However, When I turn the line-by-line code into a for-loop, It is not working as expected (only the first item and last item is updated on UI, e.g. item 1 & 5)

for (int i = 1; i < 6; i++)
{
    DelayAction(1000 * i, new Action(() => { Instance_OnATSSSignalEvent(List[i]); }));
}

Method Instance_OnATSSSignalEvent(T) will process some data and update the UI accordingly.

It is weird to me that I think the for loop is doing exactly the same as the 5 lines, But the behavior actually doesnot.

Can someone advice where did I go wrong? Thanks a lot!!


Solution

  • Currently your delayed function is using the ending value of i (in your case 6), to avoid this you can create a new local variable in each iteration of the loop:

     for (int i = 1; i < 6; i++)
            {
                var current = i;
                DelayAction(1000 * i, new Action(() => { Instance_OnATSSSignalEvent(List[current]); }));
            }