Event, bir eylemin meydana geldiğini bildirmek için bir nesne tarafından gönderilen bir bildirimdir. .NET’teki event’ler, observer design pattern’i izler.
Event’i oluşturan sınıfa Publisher (Yayımcı), bildirimi alan sınıfa Subscriber (Abone) adı verilir. Tek bir event’in birçok subscriber’ı (abonesi) olabilir. Tipik olarak, bir publisher (yayımcı) bir eylem gerçekleştiğinde bir event başlatır. Eylem gerçekleştiğinde bildirim almak isteyen subscriber’lar (aboneler) ise bir event ve handler kaydolmalıdır.
C#’ta bir event, kapsüllenmiş (encapsulated) bir delegate’dir. Event delegate bağlıdır. Delegate, subscriber sınıfının event handler metot’u için imzayı tanımlar.
Aşağıdaki şekil, C#’daki event yapısını göstermektedir.
Event Bildirimi (Declare)
Bir event iki adımda declare edilebilir:
- Delegate declare edin.
- Event anahtar sözcüğüyle delegate’in bir değişkenini bildirin.
Aşağıdaki örnek, publisher sınıfında bir event’in nasıl bildirileceğini gösterir.
Event’i deklare etmek:
public delegate void Notify(); // delegate
public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // event
}
Yukarıdaki örnekte, Notify adlı bir delegate bildirdik ve ardından ProcessBusinessLogic adlı sınıfda “event” anahtar kelimesini kullanarak Notify delegate türünden bir ProcessCompleted isimli event bildirdik. İşte burada ki ProcessBusinessLogic sınıfına publisher (yayıncı) adı verilir. Notify delegate, ProcessCompleted event handler’ın imzasını belirtir. Bu imza türünden Subscriber (abone) sınıfındaki event handler metodunun bir void dönüş türüne sahip olması ve parametre içermemesi gerektiğini anlarız.
Şimdi ProcessCompleted event’inin nasıl oluşturacağımızı görelim. Aşağıdaki uygulamayı göz önünde bulundurun.
Event’i oluşturmak:
public delegate void Notify(); // delegate
public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // event
public void StartProcess()
{
Console.WriteLine("Process Started!");
//Diğer kodlar...
OnProcessCompleted();
}
protected virtual void OnProcessCompleted()
{
//Eğer ProcessCompleted null değilse delegate çağırın
ProcessCompleted?.Invoke();
}
}
Yukarıda, StartProcess() metodunun sonu bir event başlatan onProcessCompleted() metodunu çağırır. Standart olarak, bir event’i oluşturmak için protected ve virtual bir metot On<EventName> sözdizimiyle tanımlanmalıdır.
OnProcessCompleted() metodu, ProcessCompleted?.Invoke(); koduyla delegate’i çağırır. Bu kod (invoke) ProcessCompleted
event adıyla tanımlı event handler metotları çağırır.
subscriber sınıfı (yani aboneler), ProcessCompleted event’ine kaydolmalı ve aşağıda gösterildiği gibi imzası Notify delegate’iyle eşleşen metotla işlemelidir.
Event’i Kullanma:
internal class Program
{
private static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted; // event'e kaydol
bl.StartProcess();
}
//event handler
public static void bl_ProcessCompleted()
{
Console.WriteLine("Process Completed!");
}
}
Program sınıfı, ProcessCompleted event’inin bir abonesidir (subscriber’dir). += operatörünü kullanarak event’e kaydolur. bl_ProcessCompleted() metodu, Notify delegate’nin imzasıyla eşleştiği için event’i işler.
Bütünleşik EventHandler Delegate
.NET Framework, en yaygın bütünleşik eventler için EventHandler ve EventHandler<TEventArgs> delegate türlerini içerir. Tipik olarak, herhangi bir event iki parametre içermelidir: event ve data. Event data içermeyen tüm eventler için EventHandler delegate’ini kullanın. Handler’a gönderilecek verileri içeren eventler için EventHandler<TEventArgs> delegate’ini kullanın.
Yukarıda gösterilen örnek, aşağıda gösterildiği gibi özel bir Notify delegate’i bildirmeden EventHandler delegate’ini kullanabilir.
internal class Program
{
private static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted; // event'e kaydol
bl.StartProcess();
}
//event handler
public static void bl_ProcessCompleted(object sender, EventArgs e)
{
Console.WriteLine("Process Completed!");
}
}
public class ProcessBusinessLogic
{
public event EventHandler ProcessCompleted; // event
public void StartProcess()
{
Console.WriteLine("Process Started!");
//Diğer kodlar...
OnProcessCompleted(EventArgs.Empty);
}
protected virtual void OnProcessCompleted(EventArgs e)
{
//Eğer ProcessCompleted null değilse delegate çağırın
ProcessCompleted?.Invoke(this, e);
}
}
Yukarıdaki örnekte, event handler bl_ProcessCompleted() metodu, EventHandler delegate’iyle eşleşen iki parametre içerir. Ayrıca, OnProcessCompleted() metodunda Invoke() kullanarak bir event’i oluşturduğumuzda bunu bir sender ve EventArgs.Empty olarak iletiyoruz. Event’imiz için herhangi bir veriye ihtiyacımız olmadığı için, yalnızca işlemin tamamlandığını subscribers (abonelere) bildirir ve bu nedenle EventArgs.Empty geçtik.
Event Data Gönderme
Çoğu event, abonelere bazı veriler gönderir. EventArgs sınıfı, tüm event data sınıfları için temel sınıftır. .NET, SerialDataRequiredEventArgs gibi birçok bütünleşik event data sınıfı içerir. Tüm event data sınıflarını EventArgs ile sonlandıran bir isimlendirme modelini izler. EventArgs sınıfını türeterek event dataları için özel sınıfınızı oluşturabilirsiniz.
internal class Program
{
private static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted; // event'e kaydol
bl.StartProcess();
}
//event handler
public static void bl_ProcessCompleted(object sender, bool IsSuccessful)
{
Console.WriteLine("Process " + (IsSuccessful ? "Completed Successfully" : "failed"));
}
}
public class ProcessBusinessLogic
{
public event EventHandler<bool> ProcessCompleted; // event
public void StartProcess()
{
try
{
Console.WriteLine("Process Started!");
//Diğer kodlar...
OnProcessCompleted(true);
}
catch (Exception)
{
OnProcessCompleted(false);
}
}
protected virtual void OnProcessCompleted(bool IsSuccessful)
{
ProcessCompleted?.Invoke(this, IsSuccessful);
}
}
Yukarıdaki örnekte handler’a işlemin başarılı bir şekilde tamamlanıp tamamlanmadığını gösteren tek bir boolean değeri geçiyoruz.
2 comments
Comments are closed.