piątek, 15 lutego 2013

[C#|Visual Studio] Threading: Timers

Timery dostępny w świecie .NET można podzielić na takie, które działają w obrębie jednego wątku oraz na timery wielowątkowe. Wybór zależy oczywiście głównie od potrzeb, ale także, w przypadku zegarków jednowątkowych od technologii. Mamy więc:
  • System.Windows.Forms.Timer w Windows Forms
  • System.Windows.Threading.DispatcherTimer w WPF

Multithreaded Timers

Najprostszym timerem do pracy z wieloma wątkami jest System.Threading.Timer, który składa się jedynie z konstruktora i dwóch metod.

static void ThreadingTimer()
{
    Timer tmr = new Timer (Tick, "tick...", 5000, 1000);
    Console.ReadLine();
    tmr.Dispose();
}

static void Tick (object data)
{
    Console.WriteLine (data);
}

W konstruktorze przekazujemy callback cyklicznie wywoływany, parametr tego callbacka, następnie interwał po którym pojawi się pierwsze wywołanie i interwał pomiędzy kolejnymi wywołaniami.

Bardziej rozbudowaną wersją jest Timer umiejscowiony w namespace System.Timers.  Rozszerzono API o kilka opcji zmieniając konstruktor na bezparametrowy. Ustawienia podajemy przez properties,  a ponadto możemy go wyłączać przez property Enabled, a także zatrzymywać odliczanie używając metody Stop. Sekwencja Start - Stop - Start resetuje odliczony czas.

static void TimersTimer()
{
    var tmr = new System.Timers.Timer();
    tmr.Interval = 5000;
    tmr.Elapsed += tmr_Elapsed;
    tmr.Start();
    Console.ReadLine();
    tmr.Stop(); 
    Console.ReadLine();
    tmr.Start();
    Console.ReadLine();
    tmr.Dispose();
}

static void tmr_Elapsed(object sender, EventArgs e)
{
    Console.WriteLine("Tick");
}

Oba powyższe timery wykorzystują pulę wątków, co umożliwia uruchomienie wielu ich instancji z różnych wątków. Interwał pomiędzy kolejnymi wykonaniami callbacka nie zależy od czasu wykonywania samego callbacka, a dokładność w obliczaniu czasu szacuje się na 10-20 ms.

Timery używane w WinForm i WPF dostarczają podobne API, jednak warto pamiętać, że są dedykowane do pracy w swoich środowiskach. Timery te nie wykorzystują puli wątków, natomiast w znacznej mierze zależą od mechanizmów UI, tzw. "message pumping". Zatem zdarzenie tick jest dostępne w tym samym wątku, z którego wystartowano zegarek.

Brak komentarzy:

Prześlij komentarz