c#计时器奇怪的行为

时间:2011-10-20 11:36:14

标签: c# timer

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++;
    }

fileEntries的长度为3.我创建了一个将在3秒后启动的计时器。首先,它将为fileEntries [0]执行image1.Source = GetBitmapSource(LogoImg)// 3秒,然后执行fileEntries [1] 3秒,最后执行fileEntries [2] 3秒。

但是,我的计划是这样做的:

启动计时器,运行fileEntries [0],fileEntries [1]和fileEntries [2] 0.05秒,然后等待3秒,然后重新开始。这是为什么?

2 个答案:

答案 0 :(得分:1)

您多久点击一次该按钮?

每按一次按钮,新的事件处理程序将挂钩到计时器。您永远不会取消订阅事件处理程序。

您应该在执行所需工作时阻止按钮被点击,或者您应该在再次订阅之前取消订阅。


正如Hans Passant在评论中所述,你应该考虑使用BackgroundWorker

答案 1 :(得分:0)

你不应该做

aTimer = new System.Timers.Timer(3000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimerEvent);
aTimer.Enabled = true;
aTimer.Start();
不止一次。在Form_Load事件或构造函数中执行此操作。在OnTimerEvent事件中,防止在未初始化文件时执行代码,例如

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

或者您应该在添加新事件处理程序之前取消编写。但是跟踪事件中添加了多少事件处理程序是很棘手的(或者我应该说我还没有找到办法来实现它)。

正如@Steven Jeuris所说,当一个事件处理程序被添加到一个事件时,它被文明地添加到事件处理程序LIST。因此,每当计时器过去时,列表上的每个事件处理程序都会执行,这意味着如果添加了3个事件处理程序(如您的情况),事件处理程序方法将执行3次。