简体   繁体   中英

c# timer strange behavior

private void aMethod()
    {
        aTimer = new System.Timers.Timer(3000);
        aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
        aTimer.Enabled = true;
        aTimer.Start();
    }

private void button4_Click(object sender, RoutedEventArgs e)
    {
        fileEntries = Directory.GetFiles(@"C:\Users\John\Documents\Visual Studio 2010\Projects\ComeOn\ComeOn\bin\Debug\come");
        aMethod();
        index = 0;
    }

private void OnTimerEvent(Object sender, ElapsedEventArgs e)
    {
            Bitmap LogoImg = new Bitmap(fileEntries[index]);
            LogoImg.MakeTransparent(LogoImg.GetPixel(1, 1));
            this.Dispatcher.Invoke(
                new Action(() => image1.Source = GetBitmapSource(LogoImg)));
            index++;
    }

The length of fileEntries is 3. I created a timer which will start on 3 seconds. First it will execute image1.Source = GetBitmapSource(LogoImg)//for fileEntries[0] for 3 seconds, then for fileEntries[1] for 3 seconds and in the end fileEntries[2] for 3 seconds.

But, my program does this:

Start the timer, run fileEntries[0], fileEntries[1] and fileEntries[2] for 0.05 seconds, then wait 3 seconds, then start again. Why is this?

How often did you click that button?

Every time you press the button, a new event handler will be hooked to the timer. You never unsubscribe the event handler.

You should either prevent the button from being clicked while you are performing the required work, or you should unsubscribe before subscribing again.


As Hans Passant states in his comment, you should probably also look into using a BackgroundWorker .

You shouldn't do

aTimer = new System.Timers.Timer(3000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer.Enabled = true;
aTimer.Start();

more than once. Do it in Form_Load event, or in constructor. in your OnTimerEvent event, prevent your code from being executed when files aren't initialized, for example

int index = -1;
private void OnTimerEvent(Object sender, ElapsedEventArgs e)

        {
             if(index != -1)
             {
                Bitmap LogoImg = new Bitmap(fileEntries[index]);
                LogoImg.MakeTransparent(LogoImg.GetPixel(1, 1));
                this.Dispatcher.Invoke(
                    new Action(() => image1.Source = GetBitmapSource(LogoImg)));
                index++;
             }
             if (index == 3) // when all 3 were loaded, reset index. You can also stop the timer if you won't be loading files the second time
             {
                index=-1;
             }
        }

Or you should unsuscribe before you add new event handler. But keeping track of how many event handlers are added to an event is tricky (or I should say I havn't found a way to do it yet).

As @Steven Jeuris said, when an event handler is added to an event, it is literaly ADDED, to event handlers LIST. So every time when your timer elapses every event handler on the list is executed, which means if there are 3 event handlers added (as in your case) the event handler method will execute 3 times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM