2012-11-16 4 views
12

Mam kod Windows.Forms.Timer, który wykonuję 3 razy. Jednak zegar nie wywołuje w ogóle funkcji "Tik".Timer nie zaznaczy

private int count = 3; 
private timer; 
void Loopy(int times) 
{ 
    count = times; 
    timer = new Timer(); 
    timer.Interval = 1000; 
    timer.Tick += new EventHandler(timer_Tick); 
    timer.Start(); 
} 

void timer_Tick(object sender, EventArgs e) 
{ 
    count--; 
    if (count == 0) timer.Stop(); 
    else 
    { 
     // Do something here 
    } 
} 

Loopy() jest wywoływany z innych miejsc kodu.

+1

Pierwsza odpowiedź jest prawdziwa :) –

+1

skąd dzwonisz Loopy? – Adil

+0

Funkcja Loopy() jest wywoływana z innego miejsca w kodzie. – cpdt

Odpowiedz

35

spróbuj System.Timers zamiast Windows.Forms.Timer

void Loopy(int times) 
{ 
    count = times; 
    timer = new Timer(1000); 
    timer.Enabled = true; 
    timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
    timer.Start(); 
} 

void timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    throw new NotImplementedException(); 
} 
+0

+1 za jedyną przydatną odpowiedź do tej pory. – avishayp

+0

Awesome! To działa! Nie wiem, dlaczego ... – cpdt

+2

To naprawdę nie do końca jasne, jak to naprawić problem. Zachowuje się dokładnie tak samo (ale potem znowu nie mogę odtworzyć pierwotnego problemu). – jeroenh

2

Nie jestem pewien, co robisz źle, to wygląda poprawnie, Ten kod działa: Zobacz, jak to się porównuje do twojego.

public partial class Form1 : Form 
{ 
    private int count = 3; 
    private Timer timer; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     Loopy(count); 
    } 

    void Loopy(int times) 
    { 
     count = times; 
     timer = new Timer(); 
     timer.Interval = 1000; 
     timer.Tick += new EventHandler(timer_Tick); 
     timer.Start(); 
    } 

    void timer_Tick(object sender, EventArgs e) 
    { 
     count--; 
     if (count == 0) timer.Stop(); 
     else 
     { 
      // 
     } 
    } 

} 
2

Oto Rx giełdowy, który działa:

Observable.Interval(TimeSpan.FromSeconds(1)) 
.Take(3) 
.Subscribe(x=>Console.WriteLine("tick")); 

Oczywiście, można zapisać się w coś bardziej użytecznego twój program.

+1

Naprawdę jest to najlepsza odpowiedź. Za każdym razem, gdy widzę wyraźne dodawanie lub usuwanie programów obsługi zdarzeń, szukam wstępnie upieczonego rozwiązania RX lub piszę metodę rozszerzenia, aby opakować obsługę zdarzeń. Zauważ, że Take (3) nie tylko pobiera trzy próbki z obsługi zdarzeń, dzięki czemu nie wyciekujesz pamięci. Wszystkie powyższe rozwiązania zapominają usunąć program obsługi zdarzeń po otrzymaniu zdarzeń. – bradgonesurfing

3

Jeśli metoda Loopy() zostanie wywołana w wątku, który nie jest głównym wątkiem interfejsu użytkownika, to timer nie zaznaczy. Jeśli chcesz wywołać tę metodę z dowolnego miejsca kodu, musisz sprawdzić właściwość InvokeRequired. Więc kod powinien wyglądać następująco (przy założeniu, że kod jest w formie):

 private void Loopy(int times) 
     { 
      if (this.InvokeRequired) 
      { 
       this.Invoke((MethodInvoker)delegate 
       { 
        Loopy(times); 
       }); 
      } 
      else 
      { 
       count = times; 
       timer = new Timer(); 
       timer.Interval = 1000; 
       timer.Tick += new EventHandler(timer_Tick); 
       timer.Start(); 
      } 
     }