استكشاف علاقة المفوضين والأحداث في C#
يتم إنشاء الأحداث في C# على أساس المفوضين، الذين يحددون توقيع الأسلوب لمعالجات الأحداث. بينما قدمت الوحدات السابقة أساسيات الأحداث والمفوضين، تركز هذه الوحدة على المفاهيم المتقدمة، بما في ذلك استخدام EventHandler<T>المفوضين متعددي الإرسال وأفضل الممارسات لإدارة الأنظمة المعقدة المستندة إلى الأحداث.
بينما تستمر في تطوير تطبيق متجر البيع بالتجزئة، يركز فريقك الآن على التعامل مع سيناريوهات أكثر تعقيدا، مثل إخطار أنظمة متعددة عند حدوث حدث كبير أو تمرير بيانات الحدث التفصيلية إلى المشتركين. من خلال تعلم هذه المفاهيم، يمكنك إنشاء تطبيقات قوية وقابلة للصيانة.
علاقة Delegate-Event متقدمة
المفوضون هم مؤشرات دالة آمنة من النوع تسمح بتمرير الأساليب كمعلمات واستدعاؤها ديناميكيا. بمعنى آخر، يعمل المفوض مثل "عقد" يحدد توقيع الأسلوب، ما يسمح لك بتمرير أساليب مثل المتغيرات. تغلف الأحداث المفوضين، ما يوفر طريقة منظمة لإعلام المشتركين عند حدوث شيء مهم. تستكشف هذه الوحدة كيفية استخدام المفوضين المضمنين مثل EventHandler وتبسيط EventHandler<T> معالجة الأحداث.
استخدام EventHandler<T> مع بيانات الحدث المخصصة
المفوض EventHandler<T> هو مفوض مضمن يبسط معالجة الأحداث عندما تحتاج بيانات الحدث المخصصة إلى تمريرها إلى المشتركين. يسمح لك بتعريف معالجات الأحداث التي تتضمن معلومات إضافية حول الحدث.
مثال: استخدام EventHandler<T> مع بيانات الحدث المخصصة
public class OrderEventArgs : EventArgs
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
}
public class OrderProcessor
{
// Using EventHandler<T> to define an event with custom event data
// Nullable to indicate no subscribers initially
public event EventHandler<OrderEventArgs>? OrderProcessed;
protected virtual void OnOrderProcessed(OrderEventArgs e)
{
OrderProcessed?.Invoke(this, e);
}
public void ProcessOrder(int orderId)
{
Console.WriteLine($"Processing order {orderId}...");
OnOrderProcessed(new OrderEventArgs
{
OrderId = orderId,
OrderDate = DateTime.Now
});
}
}
// Subscribing to the event
public class Program
{
public static void Main()
{
OrderProcessor processor = new OrderProcessor();
processor.OrderProcessed += (sender, e) =>
{
Console.WriteLine($"Order {e.OrderId} processed on {e.OrderDate}");
};
processor.ProcessOrder(123); // Output: "Processing order 123..."
// Output: "Order 123 processed on [current date and time]"
}
}
في هذا المثال، OrderProcessed يتم تعريف الحدث على أنه EventHandler<OrderEventArgs>?، باستخدام نوع مرجع يقبل القيم الخالية. يشير نوع المرجع الذي يقبل القيم الخالية بشكل صريح إلى أن الحدث قد لا يحتوي على أي مشتركين، ما يضمن أن التعليمات البرمجية تعالج مثل هذه السيناريوهات بأمان.
?.Invoke يضمن بناء الجملة رفع الحدث فقط إذا كان هناك مشتركون، ما يمنع الأخطاء المحتملةNullReferenceException.
تعبيرات Lambda، كما هو موضح في الاشتراك في OrderProcessed الحدث، هي طريقة قياسية لتعريف معالجات الأحداث المضمنة بشكل موجز.
مفوضو الإرسال المتعدد
يسمح مفوضو الإرسال المتعدد باستدعاء أساليب متعددة لحدث واحد. يكون مفوضو الإرسال المتعدد مفيدا عندما يحتاج العديد من المشتركين إلى الاستجابة لنفس الحدث، مثل إعلام أنظمة أو مكونات مختلفة.
مثال: استخدام المفوضين متعددي الإرسال
public class NotificationService
{
public event EventHandler? NotificationSent; // Nullable to indicate no subscribers initially
public void SendNotification()
{
NotificationSent?.Invoke(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main()
{
NotificationService service = new NotificationService();
// Subscribing multiple methods to the event
service.NotificationSent += (sender, e) => Console.WriteLine("Email notification sent!");
service.NotificationSent += (sender, e) => Console.WriteLine("SMS notification sent!");
service.SendNotification();
// Output:
// "Email notification sent!"
// "SMS notification sent!"
}
}
في هذا المثال، يتم استخدام تعبيرات lambda (=>) لتعريف معالجات الأحداث للحدث NotificationSent . غالبا ما تواجه تعبيرات Lambda مع المفوضين وتوفر طريقة موجزة وقابلة للقراءة لتعريف معالجات الأحداث، خاصة عندما يكون منطق كل معالج مباشرا.
أفضل الممارسات لإدارة الأحداث
تعد إدارة الأحداث بشكل فعال أمرا بالغ الأهمية لبناء تطبيقات قوية وقابلة للصيانة. فيما يلي بعض أفضل الممارسات التي يجب اتباعها:
تجنب تسرب الذاكرة:
قم بإلغاء الاشتراك دائما من الأحداث عندما لا تكون هناك حاجة إليها، خاصة إذا كان لدى ناشر الحدث عمر أطول من المشترك.
استخدام المراجع الضعيفة:
في السيناريوهات التي تكون فيها مدة بقاء المشترك أقصر من عمر الناشر، ضع في اعتبارك استخدام مراجع ضعيفة
WeakEventManagerأو لتجنب تسرب الذاكرة.تأكد من أمان مؤشر الترابط:
إذا تم رفع الأحداث في بيئة متعددة مؤشرات الترابط، فتأكد من أمان مؤشر الترابط باستخدام آليات المزامنة مثل الأقفال أو المجموعات الآمنة لسلسلة الرسائل.
مثال: إلغاء الاشتراك لتجنب تسرب الذاكرة
public class Subscriber : IDisposable
{
private readonly NotificationService _service;
public Subscriber(NotificationService service)
{
_service = service;
_service.NotificationSent += (sender, e) => Console.WriteLine("Notification received!");
}
public void Dispose()
{
_service.NotificationSent -= (sender, e) => Console.WriteLine("Notification received!");
}
}
الملخص
في هذه الوحدة، استكشفت المفاهيم المتقدمة للمفوضين والأحداث في C#، بما في ذلك:
- استخدام
EventHandler<T>مع بيانات الحدث المخصصة. - استخدام تعبيرات lambda لتبسيط معالجة الأحداث.
- استخدام مفوضي الإرسال المتعدد لإعلام العديد من المشتركين.
- أفضل الممارسات لإدارة اشتراكات الأحداث، وتجنب تسرب الذاكرة، وضمان أمان مؤشر الترابط.
باستخدام هذه التقنيات المتقدمة، يمكنك إنشاء تطبيقات قوية وقابلة للصيانة وقابلة للتطوير تستند إلى الحدث.