事件处理程序和经过事件处理程序有什么区别?

本文关键字:事件处理 程序 区别 什么 经过 | 更新日期: 2023-09-27 18:31:41

到目前为止,在我有限的c#使用中,我已经订阅了几个事件。为什么以下两个代码片段使用两个不同的词EventHandlerElapsedEventHandler

        myProcess = new Process();
        myProcess.StartInfo.FileName = @"notepad.exe";
        myProcess.Exited += new EventHandler(MyProcessExited);

与以下相比:

        myTimer = new System.Timers.Timer(tickLength);
        myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);

这些词是否EventHandler,并且特定于我正在使用其事件的对象ElapsedEventHandler?或者是否有一整套对象,我必须使用"事件处理程序"和另一组对象,我必须使用"经过的事件处理程序"? (即对于我们使用的对象的集合 X,xxxxxEventHandler等)

事件处理程序和经过事件处理程序有什么区别?

这些词 EventHandler 和 ElapsedEventHandler 是否特定于 对象 我正在使用谁的事件?

这句话是代表的名字。它们特定于从对象传递的信息,该对象将事件引发到该事件的订阅者。阅读下面的事件、委托和参数传递。

C# 中的事件是类在对象发生一些有趣的事情时向该类的客户端提供通知的一种方式。事件是使用委托声明的。

因此,如果你想通知客户端你的对象中发生了一些有趣的事情,你可以声明委托:

public delegate void SomethingHappenedDelegate();

并在类中声明此类型的事件:

class Foo
{
    public event SomethingHappenedDelegate SomethingHappened;
    // other code, which raises SomethingHappened event
    // when something interesting happened
}

当此类的客户端希望收到发生有趣事情的通知时,他们应该订阅 SomethingHappened 事件。并且事件处理程序签名必须与事件类型匹配(在本例中为 SomethingHappenedDelegate):

static void Main(string[] args)
{
    Foo foo = new Foo();
    foo.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened);            
}
// this method should be: void MethodName()
static void Foo_SomethingHappened()
{
    // you notified, that something happened
}

当您在通知客户端时需要传递一些其他数据时,应使用不同的委托类型,该类型需要一些参数。例如,如果要将某些消息传递给客户端,请更改事件的委托类型:

public delegate void SomethingHappenedDelegate(string message);

现在,您应该更改事件处理程序以对应此委托类型:

static void Foo_SomethingHappened(string message)
{
    // you notified, that something happened and you recieved a message
}

另一个例子,如果我们想传递对象的实例,它引发了一个事件,以及一些额外的参数消息和时间:

public delegate void SomethingHappenedDelegate(object sender, string message, DateTime time);

然后我们应该有具有相同签名的事件处理程序:

static void Main(string[] args)
{
    Foo foo1 = new Foo();
    foo1.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened);
    Foo foo2 = new Foo();
    foo2.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened); 
}
// we use same event handler for all SomethingHappened events
static void Foo_SomethingHappened(object sender, string message, DateTime time)
{
    Foo foo = sender as Foo; // now we get object, which raised event
    // and we can use message and time
}

因此,所有事件都有某种委托的类型。该委托的定义描述了哪些参数应接收方法,哪些参数将处理事件。在代码中使用两个事件 - Process.Exited 和 Timer.Elapsed。让我们看看这些事件是如何定义的:

public event EventHandler Exited;
public event ElapsedEventHandler Elapsed;

您可以在此处看到不同类型的代表:

public delegate void EventHandler(object sender, EventArgs e);
public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);

从定义中可以看出,这些委托具有相同的第一个参数(发送方)和不同的最后一个参数。因此,这些事件的处理程序也应具有不同的签名,这些签名应与这些委托匹配。

您可能想知道,为什么第二个参数的名称以 EventArgs 结尾。如果要通知其他对象,即发生了某些事情,则 C# 中存在以下约定:

  • 事件名称应SomethingHappened
  • 如果客户端需要传递一些额外的数据,这些数据封装在 Object 中,对象派生自 EventArgs 类:SomethingHappenedEventArgs
  • 事件委托应该是 EventHandler(如果不应将其他信息传递给客户端),或者它应该是泛型类型的 EventHandler <SomethingHappenedEventArgs>,或者它应该是名称为 SomethingHappenedEventHandler 且签名无效的自定义委托(对象发送方,SomethingHappenedEventArgs e)

在此处阅读更多内容。

不,事件名称是框架设计者选择的问题 + 它们与呈现任何特定对象的事件的委托紧密耦合。

EventHandler defininton 是:

[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);

ElapsedEventHandler definiton 是:

public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);

如您所见,它们是不同的delegate类型。