Example #1
0
        static void Main(string[] args)
        {
            ClassCounter Counter = new ClassCounter();
            Handler_I Handler1 = new Handler_I();
            Handler_II Handler2 = new Handler_II();

            //Подписались на событие
            Counter.onCount15 += Handler1.Message;
            Counter.onCount71 += Handler2.Message;

            Counter.Count();
        }
        public static void TestEvent()
        {
            // Событие, это не что иное, как ситуация, при возникновении которой, произойдет действие или несколько действий. Говоря языком программного моделирования, Событие — это именованный делегат, при вызове которого, будут запущены все подписавшиеся на момент вызова события методы заданной сигнатуры.
            // Эта трактовка хоть и раскрывает всю суть структуры события, но не только сбивает с толку начинающих «шарп-прогеров», но и не дает возможность рационально представить в программистской голове весь смысл. 

            // пределено три класса. Первый класс будет считать до 100, используя цикл. Два других класса будут ждать, когда в первом классе счетчик досчитает, например, до 71, и после этого каждый выведет в консоль фразу «Пора действовать, ведь уже 71!». Проще говоря, при обнаружении значения 71, вызовутся по методу, соответственно для каждого класса. Разложим все по полкам.
            // события (event) основаны на делегатах (delegate), а делегат, говоря очень простым языком — «переменная, хранящая ссылку на метод». 
            // Далее, мы создаем событие при помощи ключевого слова event и связываем его с этим делегатом (MethodContainer), а, следовательно, c методами, имеющими сигнатуру void (void). Событие должно быть public, т.к. его должны использовать разные классы, которым нужно как-то отреагировать (классы Handler_I и Handler_II). 

            ClassCounter Counter = new ClassCounter();
            Handler_I Handler1 = new Handler_I();
            Handler_II Handler2 = new Handler_II();

            //Подписались на событие
            Counter.onCount += Handler1.Message;
            Counter.onCount += Handler2.Message;

            //Запустили счетчик
            Counter.Count();

            // Класс, в котором вы создаете событие (генерируете) называется классом-издателем, а классы, чьи методы подписываются на это событие при помощи "+=" — классами-подписчиками.
            // Вы всегда можете отписаться, используя оператор "-="
            // Преимущество Событий очевидно: классу-издателю, генерирующему событие не нужно знать, сколько классов-подписчиков подпишется или отпишется. Он создал событие для определенных методов, ограничив их делегатом по определенной сигнатуре. События широко используются для составления собственных компонентов управления (кнопок, панелей, и т.д.).

            // Пару слов о .NET-событиях. Microsoft упростила задачу конструирования делегатов: .NET предлагает готовый делегат EventHandler и т.н. «пакет» входных параметров EventArgs. Желаете событие? Берете готовый EventHandler, определяетесь в параметрах, «запихиваете» их в класс, а класс наследуете от EventArgs. А дальше — как по расписанию)
            
            // EventHandler<TEventArgs> - делегат
            // Represents the method that will handle an event when the event provides data.
            // [SerializableAttribute]
            // public delegate void EventHandler<TEventArgs>(
	        //      object sender,
	        //      TEventArgs e
            // )
            // sender - The source of the event.
            // e - Type: TEventArgs. An object that contains the event data.
            // TEventArgs - The type of the event data generated by the event.
            // The event model in the .NET Framework is based on having an event delegate that connects an event with its handler.To raise an event, two elements are needed:
            // - A delegate that refers to a method that provides the response to the event.
            // - Optionally, a class that holds the event data, if the event provides data.
            // The advantage of using EventHandler<TEventArgs> is that you do not need to code your own custom delegate if your event generates event data.You simply provide the type of the event data object as the generic parameter.

            Counter c = new Counter(new Random().Next(10));
            c.ThresholdReached += c_ThresholdReached;

            Console.WriteLine("press 'a' key to increase total");
            while (Console.ReadKey(true).KeyChar == 'a')
            {
                Console.WriteLine("adding one");
                c.Add(1);
            }

            // All events in the .NET Framework class library are based on the EventHandler delegate, which is defined as follows:
            // public delegate void EventHandler(object sender, EventArgs e);
            // To publish events based on the EventHandler pattern

            MyPublisher pub = new MyPublisher();
            Subscriber sub1 = new Subscriber("sub1", pub);
            Subscriber sub2 = new Subscriber("sub2", pub);

            // Call the method that raises the event.
            pub.DoSomething();

            // Keep the console window open
            Console.WriteLine("Press Enter to close this window.");
            Console.ReadLine();
        }