Руководство по программированию на C#. Подписка и отмена подписки на событияHow to subscribe to and unsubscribe from events (C# Programming Guide)

Необходимость подписки на событие, опубликованное другим классом, может возникнуть, когда требуется написать пользовательский код, вызываемый при инициировании такого события.You subscribe to an event that is published by another class when you want to write custom code that is called when that event is raised. Например, можно подписаться на событие кнопки click, чтобы приложение выполняло некоторое действие при нажатии пользователем кнопки.For example, you might subscribe to a button's click event in order to make your application do something useful when the user clicks the button.

Подписка на события в интегрированной среде разработки Visual StudioTo subscribe to events by using the Visual Studio IDE

  1. Если окно Свойства закрыто, в представлении Конструктор щелкните правой кнопкой мыши форму или элемент управления, для которого требуется создать обработчик событий, и выберите пункт Свойства.If you cannot see the Properties window, in Design view, right-click the form or control for which you want to create an event handler, and select Properties.

  2. Вверху окна Свойства щелкните значок События.On top of the Properties window, click the Events icon.

  3. Дважды щелкните событие, которое требуется создать, например событие Load.Double-click the event that you want to create, for example the Load event.

    Visual C# создаст пустой метод обработчика событий и добавит его в код.Visual C# creates an empty event handler method and adds it to your code. Код можно также добавить вручную в представлении Код.Alternatively you can add the code manually in Code view. Например, приведенные ниже строки кода объявляют метод обработчика событий, который будет выполнен при вызове классом Form события Load.For example, the following lines of code declare an event handler method that will be called when the Form class raises the Load event.

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Add your form load event handling code here.
    }
    

    Строка кода, требуемая для подписки на событие, также создается автоматически в методе InitializeComponent в файле Form1.Designer.cs проекта.The line of code that is required to subscribe to the event is also automatically generated in the InitializeComponent method in the Form1.Designer.cs file in your project. Она имеет следующий вид:It resembles this:

    this.Load += new System.EventHandler(this.Form1_Load);  
    

Подписка на события программными средствамиTo subscribe to events programmatically

  1. Определите метод обработчика событий, сигнатура которого соответствует сигнатуре делегата для события.Define an event handler method whose signature matches the delegate signature for the event. Например, если событие основано на типе делегата EventHandler, то следующий код представляет заглушку метода:For example, if the event is based on the EventHandler delegate type, the following code represents the method stub:

    void HandleCustomEvent(object sender, CustomEventArgs a)  
    {  
       // Do something useful here.  
    }  
    
  2. Чтобы присоединить обработчик событий к событию, используйте оператор присваивания сложения (+=).Use the addition assignment operator (+=) to attach an event handler to the event. В приведенном ниже примере предположим, что объект с именем publisher имеет событие с именем RaiseCustomEvent.In the following example, assume that an object named publisher has an event named RaiseCustomEvent. Обратите внимание на то, что классу подписчика требуется ссылка на класс издателя, чтобы подписаться на его события.Note that the subscriber class needs a reference to the publisher class in order to subscribe to its events.

    publisher.RaiseCustomEvent += HandleCustomEvent;  
    

    Обратите внимание, что приведенный выше синтаксис появился только в C# 2.0.Note that the previous syntax is new in C# 2.0. Он в точности соответствует синтаксису C# 1.0, в котором с помощью ключевого слова new должен быть явно создан инкапсулирующий делегат.It is exactly equivalent to the C# 1.0 syntax in which the encapsulating delegate must be explicitly created by using the new keyword:

    publisher.RaiseCustomEvent += new CustomEventHandler(HandleCustomEvent);  
    

    Чтобы указать обработчик событий, можно также воспользоваться лямбда-выражением:You also can use a lambda expression to specify an event handler:

    public Form1()  
    {  
        InitializeComponent();  
        this.Click += (s,e) =>
            {
                MessageBox.Show(((MouseEventArgs)e).Location.ToString());
            };
    }  
    

Подписка на события с помощью анонимного методаTo subscribe to events by using an anonymous method

  • Если не нужно будет позже отменять подписку на событие, можно использовать оператор присваивания сложения (+=) для прикрепления к событию анонимного метода.If you will not have to unsubscribe to an event later, you can use the addition assignment operator (+=) to attach an anonymous method to the event. В следующем примере предположим, что объект с именем publisher имеет событие с именем RaiseCustomEvent и что класс CustomEventArgs также был определен и содержит некие относящиеся к событию сведения.In the following example, assume that an object named publisher has an event named RaiseCustomEvent and that a CustomEventArgs class has also been defined to carry some kind of specialized event information. Обратите внимание на то, что классу подписчика требуется ссылка на publisher, чтобы подписаться на его события.Note that the subscriber class needs a reference to publisher in order to subscribe to its events.

    publisher.RaiseCustomEvent += delegate(object o, CustomEventArgs e)  
    {  
      string s = o.ToString() + " " + e.ToString();  
      Console.WriteLine(s);  
    };  
    

    Важно отметить, что отменить подписку на событие не так просто, если для подписки на него использовалась анонимная функция.It is important to notice that you cannot easily unsubscribe from an event if you used an anonymous function to subscribe to it. Чтобы отменить подписку в этом случае, необходимо вернуться к коду, в котором была выполнена подписка на событие, сохранить анонимный метод в переменной делегата, а затем добавить делегат к событию.To unsubscribe in this scenario, it is necessary to go back to the code where you subscribe to the event, store the anonymous method in a delegate variable, and then add the delegate to the event. Как правило, мы рекомендуем не использовать анонимных функций для подписки на события, если предполагается, что в будущем будет нужно отменять подписку на событие.In general, we recommend that you do not use anonymous functions to subscribe to events if you will have to unsubscribe from the event at some later point in your code. Дополнительные сведения об анонимных функциях см. в разделе Анонимные функции.For more information about anonymous functions, see Anonymous Functions.

Отмена подпискиUnsubscribing

Чтобы предотвратить вызов обработчика событий при инициировании события, подписку на событие необходимо отменить.To prevent your event handler from being invoked when the event is raised, unsubscribe from the event. Во избежание утечки ресурсов отменять подписку на события следует до удаления объекта подписчика.In order to prevent resource leaks, you should unsubscribe from events before you dispose of a subscriber object. До тех пор пока подписка на событие не отменена, делегат многоадресной рассылки, лежащий в основе события в публикующем объекте, будет ссылаться на делегат, инкапсулирующий обработчик событий подписчика.Until you unsubscribe from an event, the multicast delegate that underlies the event in the publishing object has a reference to the delegate that encapsulates the subscriber's event handler. Если ссылка присутствует в публикующем объекте, объект подписчика не будет удален при сборке мусора.As long as the publishing object holds that reference, garbage collection will not delete your subscriber object.

Отмена подписки на событиеTo unsubscribe from an event

  • Чтобы отменить подписку на событие, воспользуйтесь оператором присваивания вычитания (-=).Use the subtraction assignment operator (-=) to unsubscribe from an event:

    publisher.RaiseCustomEvent -= HandleCustomEvent;  
    

    Если подписка на событие отменена для всех подписчиков, экземпляр события в классе издателя получает значение null.When all subscribers have unsubscribed from an event, the event instance in the publisher class is set to null.

См. также разделSee also