Porównanie timera z DispatcherTimer

98

jaka jest różnica between System.Windows.Forms.Timer()i System.Windows.Threading.DispatcherTimer()? W jakich przypadkach powinniśmy ich używać? jakieś najlepsze praktyki?

paradisonoir
źródło

Odpowiedzi:

111

Windows.Forms.Timerużywa pętli komunikatów formularzy Windows do przetwarzania zdarzeń czasowych. Powinien być używany podczas pisania zdarzeń czasu, które są używane w aplikacjach Windows Forms i chcesz, aby licznik czasu był uruchamiany w głównym wątku interfejsu użytkownika.

DispatcherTimerjest mechanizmem czasowym WPF. Powinien być używany, gdy chcesz obsługiwać synchronizację w podobny sposób (chociaż nie jest to ograniczone do pojedynczego wątku - każdy wątek ma swój własny dyspozytor) i używasz WPF. Wywołuje zdarzenie w tym samym wątku co Dispatcher.

Ogólnie WPF == DispatcherTimeri Windows Forms == Forms.Timer.

Biorąc to pod uwagę, istnieje również System.Threading.Timer, który jest zegarem, classktóry uruchamia się w osobnym wątku. Jest to dobre dla czysto numerycznego pomiaru czasu, w którym nie próbujesz aktualizować interfejsu użytkownika itp.

Reed Copsey
źródło
1
Dzięki za szybką odpowiedź. Oznacza to, że ilekroć chcę mieć timer związany z UI, powinienem użyć DispatcherTimer, a gdy chcę odpalić timer, którego nie chcę zamrażać UL, powinienem użyć System.Threading.Timer w osobnym wątek. Drugie pytanie brzmi: jeśli chcę używać DispatcherTimer i chcę, aby zegar nie był powiązany z interfejsem użytkownika, czy powinienem wywołać go w oddzielnym wątku za pomocą System.Threading.Timer, czy nadal DisptacherTimer?
paradisonoir
3
To zależy od tego, co próbujesz zrobić. Rzadko używam System.Threading.Timer - zwykle trzymam się Dispatcher Timer, a następnie wykonuję swoją PRACĘ (która może blokować twój interfejs użytkownika) w innym wątku, używając czegoś takiego jak BackgroundWorker. Liczniki czasu naprawdę nigdy nie powinny blokować interfejsu użytkownika, chyba że wykonujesz „zbyt dużo” pracy w ich module obsługi zdarzeń.
Reed Copsey,
Mam problem z tym, że DispatcherTimer z czasem zużywa procesor. Czy jest dobry sposób, aby sobie z tym poradzić?
discorax
Sprawdź, co konkretnie pochłania procesor. Czy tworzysz wiele timerów, które nie są zatrzymywane?
Reed Copsey
3
Upewnij się, że właściwość interwału została ustawiona poprawnie. Nie rób tego: timer1.Interval = new TimeSpan (1000); // „1000” reprezentuje tyknięcia, a nie milisekundy! Procesor był bardzo wysoki, dopóki nie poprawiłem go w ten sposób: timer1.Interval = System.TimeSpan.FromSeconds (1);
Lonnie Best
4

Znalazłem dobry artykuł na temat timerów z małymi przykładami tutaj: http://www.progware.org/Blog/post/Timers-in-WPF.aspx

Jako podsumowanie:

Jeśli DoSomething () manipuluje komponentami GUI, to za pomocą Timera musisz użyć: this.Dispatcher.Invoke ((Action) delegate {// GUI RELATED CODE HERE}, ponieważ nie możesz uzyskać dostępu do kontrolek GUI bezpośrednio z innego wątku. nie trzeba tego robić.

Jeśli DoSomething () wykona czasochłonne zadanie, to GUI zawiesi się w przypadku DispatcherTimer. W przypadku Timera tak się nie stanie, ponieważ długie metody są wykonywane w innym wątku

Seekeer
źródło