2011-10-20 4 views
0
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++; 
    } 

La longueur de fileEntries est de 3. J'ai créé une minuterie qui démarrera sur 3 secondes. D'abord, il exécutera image1.Source = GetBitmapSource (LogoImg) // pour fileEntries [0] pendant 3 secondes, puis pour fileEntries [1] pendant 3 secondes et à la fin fileEntries [2] pendant 3 secondes.C# minuterie comportement étrange

Mais, mon programme fait ceci:

Démarrer la minuterie, exécutez fileEntries [0], fileEntries [1] et fileEntries [2] pour 0,05 secondes, puis attendez 3 secondes, puis recommencez. Pourquoi est-ce?

+0

Où 'index' est-il déclaré et initialisé? – ChrisF

+0

Avez-vous essayé de définir unTimer.AutoReset = false? –

+0

@Lucasus Oui, ça n'aide pas. –

Répondre

0

Vous ne devriez pas faire

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

plus d'une fois. Faites-le dans l'événement Form_Load ou dans le constructeur. dans votre cas OnTimerEvent, empêcher votre code d'être exécuté lorsque les fichiers ne sont pas initialisés, par exemple

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

Ou vous devez désinscrire avant d'ajouter nouveau gestionnaire d'événements. Mais garder une trace du nombre de gestionnaires d'événements ajoutés à un événement est délicat (ou devrais-je dire que je n'ai pas encore trouvé de moyen de le faire). Comme l'a dit @Steven Jeuris, lorsqu'un gestionnaire d'événements est ajouté à un événement, il est littéralement ajouté à la liste LIST des gestionnaires d'événements. Ainsi, chaque fois que votre temporisateur s'écoule, chaque gestionnaire d'événement de la liste est exécuté, ce qui signifie que s'il y a 3 gestionnaires d'événements ajoutés (comme dans votre cas), la méthode du gestionnaire d'événements s'exécutera 3 fois.

+0

_ "Mais il est difficile de savoir combien de gestionnaires d'événements sont ajoutés à un événement" _ Vous voulez clarifier pourquoi vous voudriez faire cela? –

+0

J'ai récemment eu un problème avec le gestionnaire d'événements s'abonnant à un objet pour la deuxième et troisième fois lorsque j'ai disposé de l'objet et ensuite créé un autre avec le même nom. Bizarrement, le gestionnaire d'événements précédemment abonné existait encore. Sachant combien de gestionnaires d'événements j'ai à ce moment-là aurait été très utile pour moi, mais je n'ai pas trouvé un moyen de le faire. – Arie

+0

Tnx, ça m'a vraiment aidé :) –

1

À quelle fréquence avez-vous cliqué sur ce bouton?

Chaque fois que vous appuyez sur le bouton, un nouveau gestionnaire d'événements est connecté au temporisateur. Vous ne vous désinscrivez jamais du gestionnaire d'événements.

Vous devez soit éviter de cliquer sur le bouton pendant que vous effectuez le travail requis, soit vous désinscrire avant de vous abonner à nouveau.


Comme Hans indique dans son Passant commentaire, vous devriez probablement aussi en utilisant un BackgroundWorker.