Handling and Raising Events

.NET Framework 4.5
 
Other Versions
 
 
6 out of 20 rated this helpful - Rate this topic
 

Events in the .NET Framework are based on the delegate model. The delegate model follows the observer design pattern, which enables a subscriber to register with, and receive notifications from, a provider. An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

For information about handling events in Windows Store apps, see Events and routed events overview (Windows store apps).

An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a button click, or it could be raised by some other program logic, such as changing a property’s value. The object that raises the event is called the event sender. The event sender doesn't know which object or method will receive (handle) the events it raises. The event is typically a member of the event sender; for example, theClick event is a member of the Button class, and the PropertyChanged event is a member of the class that implements the INotifyPropertyChangedinterface.

To define an event, you use the event (in C#) or Event (in Visual Basic) keyword in the signature of your event class, and specify the type of delegate for the event. Delegates are described in the next section.

Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Name this method OnEventName; for example, OnDataReceived. The method should take one parameter that specifies an event data object. You provide this method to enable derived classes to override the logic for raising the event. A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.

The following example shows how to declare an event named ThresholdReached. The event is associated with the EventHandler delegate and raised in a method named OnThresholdReached.

 
class Counter
{
public event EventHandler ThresholdReached; protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
} // provide remaining implementation for the class
}

A delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is sufficient to define a delegate class.

Delegates have many uses in the .NET Framework. In the context of events, a delegate is an intermediary (or pointer-like mechanism) between the event source and the code that handles the event. You associate a delegate with an event by including the delegate type in the event declaration, as shown in the example in the previous section. For more information about delegates, see the Delegate class.

The .NET Framework provides the EventHandler and EventHandler<TEventArgs> delegates to support most event scenarios. Use the EventHandlerdelegate for all events that do not include event data. Use the EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return type value and take two parameters (an object for the source of the event and an object for event data).

Delegates are multicast, which means that they can hold references to more than one event-handling method. For details, see the Delegate reference page. Delegates provide flexibility and fine-grained control in event handling. A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event.

For scenarios where the EventHandler and EventHandler<TEventArgs> delegates do not work, you can define a delegate. Scenarios that require you to define a delegate are very rare, such as when you must work with code that does not recognize generics. You mark a delegate with the delegate in (C#) and Delegate (in Visual Basic) keyword in the declaration. The following example shows how to declare a delegate namedThresholdReachedEventHandler.

 
public delegate void ThresholdReachedEventHandler(ThresholdReachedEventArgs e);

Data that is associated with an event can be provided through an event data class. The .NET Framework provides many event data classes that you can use in your applications. For example, the SerialDataReceivedEventArgs class is the event data class for the SerialPort.DataReceived event. The .NET Framework follows a naming pattern of ending all event data classes with EventArgs. You determine which event data class is associated with an event by looking at the delegate for the event. For example, the SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.

The EventArgs class is the base type for all event data classes. EventArgs is also the class you use when an event does not have any data associated with it. When you create an event that is only meant to notify other classes that something happened and does not need to pass any data, include the EventArgsclass as the second parameter in the delegate. You can pass the EventArgs.Empty value when no data is provided. The EventHandler delegate includes theEventArgs class as a parameter.

When you want to create a customized event data class, create a class that derives from EventArgs, and then provide any members needed to pass data that is related to the event. Typically, you should use the same naming pattern as the .NET Framework and end your event data class name with EventArgs.

The following example shows an event data class named ThresholdReachedEventArgs. It contains properties that are specific to the event being raised.

 
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}

To respond to an event, you define an event handler method in the event receiver. This method must match the signature of the delegate for the event you are handling. In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user clicks a button. To receive notifications when the event occurs, your event handler method must subscribe to the event.

The following example shows an event handler method named c_ThresholdReached that matches the signature for the EventHandler delegate. The method subscribes to the ThresholdReached event.

 
class Program
{
static void Main(string[] args)
{
Counter c = new Counter();
c.ThresholdReached += c_ThresholdReached; // provide remaining implementation for the class
} static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
}

The .NET Framework allows subscribers to register for event notifications either statically or dynamically. Static event handlers are in effect for the entire life of the class whose events they handle. Dynamic event handlers are explicitly activated and deactivated during program execution, usually in response to some conditional program logic. For example, they can be used if event notifications are needed only under certain conditions or if an application provides multiple event handlers and run-time conditions define the appropriate one to use. The example in the previous section shows how to dynamically add an event handler. For more information, see Events (Visual Basic) and Events (C# Programming Guide).

If your class raises multiple events, the compiler generates one field per event delegate instance. If the number of events is large, the storage cost of one field per delegate may not be acceptable. For those situations, the .NET Framework provides event properties that you can use with another data structure of your choice to store event delegates.

Event properties consist of event declarations accompanied by event accessors. Event accessors are methods that you define to add or remove event delegate instances from the storage data structure. Note that event properties are slower than event fields, because each event delegate must be retrieved before it can be invoked. The trade-off is between memory and speed. If your class defines many events that are infrequently raised, you will want to implement event properties. For more information, see How to: Handle Multiple Events Using Event Properties.

 

Title

Description

How to: Raise and Consume Events

Contains examples of raising and consuming events.

How to: Handle Multiple Events Using Event Properties

Shows how to use event properties to handle multiple events.

Observer Design Pattern

Describes the design pattern that enables a subscriber to register with, and receive notifications from, a provider.

How to: Consume Events in a Web Forms Application

Shows how to handle an event that is raised by a Web Forms control.

Did you find this helpful? Yes No
 

(C#) Handling and Raising Events的更多相关文章

  1. mysql Error Handling and Raising in Stored Procedures

    MySQL的存储过程错误捕获方式和Oracle的有很大的不同. MySQL中可以使用DECLARE关键字来定义处理程序.其基本语法如下: DECLARE handler_type HANDLER FO ...

  2. C#委托及事件处理机制浅析

    事件可以理解为某个对象所发出的消息,以通知特定动作(行为)的发生或状态的改变.行为的发生可能是来自用户交互,如鼠标点击:也可能源自其它的程序逻辑.在这里,触发事件的对象被称为事件(消息)发出者(sen ...

  3. webform CustomValidator

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.customvalidator?view=netframew ...

  4. cakephp 的事件系统(Getting to grips with CakePHP’s events system), 基于观察者模式

    This article was written about CakePHP 2.x and has been untested with CakePHP 3.x CakePHP seems to g ...

  5. Explaining Delegates in C# - Part 3 (Events 2)

    I was thinking that the previous post on Events and Delegates was quite self-explanatory. A couple o ...

  6. Explaining Delegates in C# - Part 2 (Events 1)

    In my previous post, I spoke about a few very basic and simple reasons of using delegates - primaril ...

  7. Handling of asynchronous events---reference

    http://www.win.tue.nl/~aeb/linux/lk/lk-12.html 12. Handling of asynchronous events One wants to be n ...

  8. Getting to grips with CakePHP’s events system

    CakePHP seems to get a slightly unfavourable reputation when compared to the likes of Symfony or Zen ...

  9. Console Event Handling

    http://www.codeproject.com/Articles/2357/Console-Event-Handling Console Event Handling Kumar Gaurav ...

随机推荐

  1. USACO 1.3.6 Ski Course Design[滑雪课程设计]

    先说说思路: 这题比上一道坑人的wormholes简单多了!我一看到这题,“XXX设计”,还以为要用到什么dp呢,没想到是水题 用两层循环,第一层循环相差17中的上界,第二层遍历所有的山峰计算答案.并 ...

  2. 关于STM32F407启动后的系统时钟频率问题

    玩STM32的时间也比较久了,最早的一直玩的是STD标准库的103系列,但是ST公司也是“与时俱进”,舍弃了当年的标准库,转而推广HAL库,反正无论怎么样把,对于STM32的使用也仅仅停留在使用阶段, ...

  3. 查看php 相关信息

    PHP系统常量 __FILE__ 当前PHP程序脚本的绝对路径及文件名称 __LINE__ 存储该常量所在的行号 __FUNCTION__ 存储该常量所在的函数名称 __CLASS__ 存储该常量所在 ...

  4. 自定义Razor 标签

    1.首先需要一个abstract class WebViewPage<T> ,继承系统的 System.Web.Mvc.WebViewPage<TModel> 再定义一个Web ...

  5. day33 GIL锁 线程队列 线程池

    1.    全局解释器锁GIL Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行.虽然 Python 解释器中可 ...

  6. Arm寄存器介绍及汇编基础

    一.ARM处理器支持7种工作模式 ① 用户模式(USR): 用于正常执行程序(The normal ARM program execution state) ② 快速中断模式(FIQ): 用于高速数据 ...

  7. 9.ORM数据访问

    1.Spring对ORM的支持 ORM : 对象关系映射(Object Relational Mapping)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术基于ORM的数据持久层框架有: ...

  8. Zabbix sql注入漏洞脚本执行反弹shell

    exp检测是否存在SQL注入漏洞root@ubuntu:~# python zabbix.py http://ip:9090/+------------------------------------ ...

  9. Angular JS ng-repeat 报错 Error: [ngRepeat:dupes]

    ng-repeat常用情况: <div class="form-group" ng-repeat="item in items"></div& ...

  10. input校验不能以0开头的数字

    不以零开头 <input type="text"  class="form-control"  onkeyup="value=value.rep ...