【问题标题】:C#: Multiple Event RaisesC#:多个事件引发
【发布时间】:2012-02-17 11:01:14
【问题描述】:

我的问题与事件有关:

我有一个带有TaskAComplete 事件的类,该事件在TaskA 完成时引发。

当按下按钮时,我订阅TaskACompleteEvent

MyObject.TaskAComplete += new EventHandler(MethodToCall);

但在其他事件中,我想在事件第一次发生时取消订阅 TaskAComplete 事件。

与:

MyObject.TaskAComplete -= MethodToCall;

然后当下次按下按钮时再次订阅TaskAComplete事件。

现在,当我启动应用程序并第一次单击按钮时,它会正确引发事件。但是当我第二次单击按钮时,事件会连续引发两次。 (第三次点击 -> 事件连续引发三次,依此类推..)

当我在表单的构造函数中订阅事件时,每次点击它只会引发一次。

为什么事件会来几次?

【问题讨论】:

    标签: c# .net events


    【解决方案1】:

    当您订阅一个事件时,您通过向一个方法提供一个委托来进行订阅。委托实际上是 C/C++ 函数指针的强类型、面向对象的方法。

    然后此委托进入事件调用列表。

    当您执行new EventHandler(MethodToCall) 时,您将明确创建该委托。但是,当您执行-= MethodToCall 时,您将删除一个“自动”委托。就好像你写了-= new EventHandler(MethodToCall)。显然,这个新委托不在调用列表中。

    要做你想做的事,在添加时,你需要将新的委托保存在一个变量中,以后可以删除它。例如:

    var handler = new EventHandler(MethodToCall);
    MyObject.TaskAComplete += handler;
    // later on
    MyObject.TaskAComplete -= handler;
    

    【讨论】:

    • 我试过你的建议,但没有奏效!!我再次收到多个事件!我所做的:创建一个成员变量“handler”作为 EventHandler,然后在构造函数中使用 new 为其分配一个“MethodToCall”,使用 MyObject.TaskComplete += 处理程序在 Button_Click 方法处订阅事件,然后使用 MyObject 取消订阅。 TaskComplete -= 另一个事件方法中的处理程序,对吗?
    【解决方案2】:

    您只需订阅该事件一次。如果您使用同一个处理程序多次订阅,则该处理程序将被多次调用,就像您看到的一样。

    您首先为什么要取消订阅TaskAComplete 事件?如果您的其他代码是正确的,您将在每个任务中只得到一次。

    【讨论】:

    • 我有类似状态机的东西,我在不同的状态下允许或不允许不同的事件。这就是我需要阻止事件的原因。怎么可能做到?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多