This article is currently in the process of being translated into Turkish (~95% done).
The DispatcherTimer
Windows Forms(WinForms)'da Timer diye bir kontrol vardı. Bu kontrol ile belirli zaman aralıklarında birşeyler çalıştırabiliyorduk. WPF'te de bunu yapmamız mümkün ancak WinForms'taki görünmez bir kontrol yerine normal bir kontrol olan DispatcherTimer ile bunu yapıyoruz. Tek fark Timer nesnesini yaratma şeklinde. WinForms'taki sürekle bırak ile yaratmak yerine, WPF'teki DispatcherTimer nesnesi XAML dokümanının kod kısmında elle ile yaratılır.
DispatcherTimer nesnesi ile çalışabilmeniz için bir zaman aralığı vermeli ve her zaman aralığının sonunda tetiklenecek olan Tick event'ine kayıt olmalısınız. Ayrıca DispatcherTimer siz Start() metodunu açıkça çağırmadan veya IsEnabled özelliğini true yapmadan başlamayacaktır.
Hadi gelin ve basit bir dijital saat yapmak için DispatcherTimer nesnesinin nasıl kullanılacağına dair bir örneğe bakalım.
<Window x:Class="WpfTutorialSamples.Misc.DispatcherTimerSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DispatcherTimerSample" Height="150" Width="250">
<Grid>
<Label Name="lblTime" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfTutorialSamples.Misc
{
public partial class DispatcherTimerSample : Window
{
public DispatcherTimerSample()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToLongTimeString();
}
}
}
XAML kısmı aşırı basit. Sadece güncel zamanı göstermek için kullanılan, büyük fontlu, ortaya hizalanmış bir Label'dan oluşuyor.
Kod kısmı asıl büyünün gerçekleştiği yer. Penceremizin kurucusunda DispatcherTimer nesnesinin bir örneğini yaratıyoruz. Interval özelliğini 1 saniyeye ayarlayıp, Tick olayına kayıt olduktan sonra Timer'ı başlatıyoruz. Tick olayında ise güncel zamanı göstermek için basitçe Label'ı güncelliyoruz.
Tahmin edeceğiniz üzere DispatcherTimer nesnesi daha küçük veya büyük zaman aralılarında çalışabilir. Mesala 30 saniyede veya 5 dakikada bir birşeyin gerçekleşmesini isteyebilirsiniz. Bu tarz bir durumda TimeSpan sınıfının TimeSpan.From* metotlarından FromSeconds veya FromMinutes kullanabilirsiniz veya ihtiyaçlarınıza tamamen uyabilecek bir TimeSpan nesnesi yaratabilirsiniz.
DispatcherTimer nesnesinin yeteneklerini görebilmek için, hadi daha sık zaman aralıklarında Label'a güncelleme yapalım!
using System;
using System.Windows;
using System.Windows.Threading;
namespace WpfTutorialSamples.Misc
{
public partial class DispatcherTimerSample : Window
{
public DispatcherTimerSample()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
lblTime.Content = DateTime.Now.ToString("HH:mm:ss.fff");
}
}
}
Gördüğünüz gibi DispatcherTimer'ımız her bir milisaniyede bir tetiklenmesini istiyoruz! Ayrıca Label'ın içinde milisaniyeleri görebilmemiz için Tick event'inde özel bir zaman format string'i kullandık. Şimdi isterseniz birkaç buton ekleyip Timer'ın Stop(), Start() ve Restart() metotlarına bağlayarak, Stopwatch gibi kullanılabilecek bir şeye sahip olabilirsiniz.
Özet
Uygulamarınızda belli zaman aralıklarında gerçekleşmesini istediğiniz birşeylerin olduğu birçok durumla karşılaşabilirsiniz ve bir DispatcherTimer nesnesi kullanarak bunu halletmek oldukça kolay. Sadece eğer Tick event'inde karmaşık (karmaşıktan kastım uzun süren bir kod parçası) birşey yapıyorsanız, bir önceki milisaniyeli örnekte olduğu gibi Tick event'i çok sık tetiklenmediğinden emin olun. Aksi taktirde bu uygulamanızın çalıştığı bilgisayara ağır bir yük binderecektir.
Ayrıca DispatcherTimer her zaman %100 hassas olmadığının farkında olun. Tick event'leri Dispatcher kuyruğuna yerleştirilir. Bu sebepler bilgisayarınız bir yük altında ise, bu Tick işleminin gecikebileceği anlamına gelir. .Net Framework ve .Net Tick event'inin asla zamanından önce tetiklenmeyeceğinin fakat gecikebileceği konusunda bir taahhüt vermekte. Bununla birlikte çoğu durum için, DispatcherTimer yeterince hassas olacaktır.
Eğer Timer'ınızın kuyrukta daha yüksek bir önceliğe sahip olmasını isterseniz, DispatcherPriority'sini daha yüksek bir değere atayabilirsiniz. Bununla ilgili detaylı bilgi için MSDN makalesini okuyabilirsiniz.