هندسة Event-Driven في C#: كيفية إدارة الأحداث كالمحترفين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لماذا يستيقظ كودك فقط عند الاتصال؟

\n

تخيل أنك مراقب في مطار ضخم. الطائرات تصل، الركاب يسرعون، شاحنات الوقود تناور. إذا كنت تذهب شخصياً إلى كل طيار وتسأل: "هل هبطت؟ والآن؟ والآن؟" - ستصاب بالجنون. بدلاً من ذلك، تقول: "عندما تهبط - اتصل". والنظام يعمل بشكل مثالي.

\n

هذه هي هندسة Event-Driven في C#. بدلاً من الاستفسار المستمر عن الكائنات (pull)، نشترك في الأحداث (push). يصبح الكود تفاعلياً، قابلاً للتوسع، والأهم من ذلك - حياً. في هذه المقالة، سنشرح كيفية بناء مثل هذه الأنظمة في C# من الصفر، باستخدام الآليات المدمجة في اللغة والأنماط المتقدمة.

\n\n

ما هي هندسة Event-Driven؟ ليست نظرية مملة

\n

هندسة Event-Driven (الموجهة بالأحداث) هي نهج يتم فيه تحديد تدفق تنفيذ البرنامج بواسطة الأحداث: نقرات، رسائل من قوائم الانتظار، تغييرات في البيانات أو إشارات خارجية. في C#، هذا المفهوم مدمج مباشرة في اللغة من خلال المفوضين (delegates) والأحداث (events).

\n

المبدأ الرئيسي هو الاقتران الضعيف (loose coupling). مرسل الحدث (الناشر) لا يعرف شيئاً عن المستقبلين (المشتركين). هو فقط يصرخ: "حدث شيء مهم!" - ومن وكيف سيتفاعل مع ذلك، يُقرر ديناميكياً.

\n

لماذا هذا رائع للمشاريع الحقيقية؟

\n
    \n
  • قابلية التوسع: إضافة مشترك جديد - مثل اشتراكه في قائمة بريدية. كود الناشر لا يتغير.
  • \n
  • قابلية الاختبار: يمكنك اختبار المشتركين بشكل منعزل، بتزويدهم بأحداث وهمية.
  • \n
  • التفاعلية: النظام يتفاعل تلقائياً مع التغييرات، دون إهدار الموارد على استفسارات فارغة.
  • \n
\n\n

الآلية الأساسية: المفوضين والأحداث في C#

\n

قبل بناء الهندسة، دعنا نفهم الأساس. في C#، الحدث هو مجرد مفوض متخصص مع معدّل event. المفوض هو نوع يخزن مرجعاً لدالة (أو عدة دوال).

\n\n

كتابة أول كود Event-Driven

\n

تخيل أننا نكتب نظام منزل ذكي. مستشعر الحركة يرسل إشارة عندما يدخل شخص ما.

\n\n
public class MotionSensor\n{\n    // 1. نعلن عن المفوض (نوع الحدث)\n    public delegate void MotionDetectedHandler(object sender, MotionEventArgs e);\n    \n    // 2. نعلن عن الحدث\n    public event MotionDetectedHandler OnMotionDetected;\n\n    public void Detect(string location)\n    {\n        Console.WriteLine($"[مستشعر] حركة في {location}!");\n        \n        // 3. نستدعي الحدث (فقط إذا كان هناك مشتركون)\n        OnMotionDetected?.Invoke(this, new MotionEventArgs(location));\n    }\n}\n\npublic class MotionEventArgs : EventArgs\n{\n    public string Location { get; }\n    public DateTime Timestamp { get; } = DateTime.UtcNow;\n\n    public MotionEventArgs(string location)\n    {\n        Location = location;\n    }\n}\n\n// المشترك - المصباح\npublic class SmartLight\n{\n    public void OnMotion(object sender, MotionEventArgs e)\n    {\n        if (e.Location == "غرفة المعيشة")\n            Console.WriteLine($"[مصباح] أشغل الضوء في {e.Location}!");\n        else\n            Console.WriteLine($"[مصباح] أتجاهل {e.Location}.");\n    }\n}\n\n// الاستخدام\nvar sensor = new MotionSensor();\nvar light = new SmartLight();\n\n// نشترك بالمصباح في حدث المستشعر\nsensor.OnMotionDetected += light.OnMotion;\n\nsensor.Detect("غرفة المعيشة"); // المصباح سيعمل\nsensor.Detect("المطبخ");    // "أتجاهل المطبخ."
\n\n

مهم: استخدام ?.Invoke هو طريقة آمنة للخيوط لاستدعاء الحدث. بدون التحقق من null، تخاطر بالحصول على NullReferenceException إذا لم يكن هناك مشتركون.

\n\n

المستوى المتقدم: EventBus والاقتران الضعيف

\n

الاشتراكات المباشرة جيدة لـ

المدونات

توصيات الكتب