2009-04-07 8 views
4

Original post: How to access a timer from another class in C#Comment activer une minuterie à partir d'un autre fil/classe

J'ai tout essayé.

-Event

-Invoke ne peut pas être fait, parce que Timers ne pas avoir la propriété InvokeRequired.

-Santé/propriété interne

Rien n'a fonctionné, le code est en cours d'exécution, la propriété timer.Enabled est réglé sur « true », mais il ne Tick.If que j'appelle l'événement ou tout simplement le changement la propriété de la classe de formulaire dans une méthode NON-statique - elle cochée et fonctionne.

Je ne savais pas qu'il me faudrait un jour et probablement plus pour apprendre à utiliser une minuterie décente.

S'il n'y a aucun moyen de le faire, y a-t-il autre chose que je puisse utiliser qui fonctionne de la même manière que la minuterie (retard, activation/désactivation)?

+0

John, s'il vous plaît ajouter à votre question précédente (Vous pouvez modifier votre message), car cela serait plus utile aux autres utilisateurs ayant le même problème. –

+0

duplicata possible de http://stackoverflow.com/questions/725413/how-to-access-a-timer-from-another-class-in-c – raven

Répondre

7

Vous devez utiliser la classe Timer de l'espace de noms System.Timers, et non le contrôle WinForms Timer, si vous souhaitez un support multithread. Consultez la documentation MSDN pour le WinForms contrôle minuterie pour plus d'informations:

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx

+0

+1 pour me battre dessus :-) –

+0

A été surpris de Soyez le premier à celui-ci ... –

+1

Bien que cela déclenche l'événement Elapsed (le System.Timer.Timer a un événement Elapsed par opposition à l'événement Tick de System.Windows.Forms.Timer), il se déclenche dans le Le contexte du thread appelant et, en fonction de ce que vous faites dans l'événement, peut entraîner une exception System.InvalidOperationException, par exemple, "Opération inter-thread non valide: Control 'X' accédé à partir d'un thread autre que le thread sur lequel il a été créé " – raven

1

Je accidentellement essayé d'utiliser invoquer à nouveau, cette fois cela a fonctionné, mais je vais accepter votre réponse, DavidM.

public bool TimerEnable 
    { 
     set 
     { 
      this.Invoke((MethodInvoker)delegate 
      { 
       this.timer.Enabled = value; 
      }); 
     } 
    } 


    public static void timerEnable() 
    { 
     var form = Form.ActiveForm as Form1; 
     if (form != null) 
      form.TimerEnable = true; 
    } 
+0

Que faire si votre minuteur est dans un autre cours? Vous ne serez pas capable d'invoquer avec 'this'. Je pense qu'une approche évolutive est par @David M – nawfal

+0

merci de demander, honte à moi pour prendre soin de passer une journée ... – kubilay

1

Tout simplement parce que System.Windows.Forms.Timer n'a pas la possibilité d'invoquer, ne signifie pas que votre formulaire ne fonctionne pas. Essayez mon InvokeEx à partir du deuxième thread (ou autre) pour activer le minuteur.

public static class ControlExtensions 
{ 
    public static TResult InvokeEx<TControl, TResult>(this TControl control, 
          Func<TControl, TResult> func) 
    where TControl : Control 
    { 
    if (control.InvokeRequired) 
    { 
     return (TResult)control.Invoke(func, control); 
    } 
    else 
    { 
     return func(control); 
    } 
    } 
} 

Avec cela, le code suivant a fonctionné pour moi:

new Thread(() => 
    { 
    Thread.Sleep(1000); 
    this.InvokeEx(f => f.timer1.Enabled = true); 
    }).Start(); 

Et la minuterie instantanément cintrées à la vie après la 1 seconde.

6

Vous n'avez pas besoin de vérifier InvokeRequired sur le contrôle iteself, vous pouvez vérifier la propriété sur le par exemple de classe:

if (this.InvokeRequired) 
{ 
    BeginInvoke(new MyDelegate(delegate() 
    { 
     timer.Enabled = true; 
    })); 
} 
Questions connexes