【问题标题】:Does an event gets executed twice if callback was assigned twice to the object?如果将回调分配给对象两次,事件是否会执行两次?
【发布时间】:2010-02-15 00:53:51
【问题描述】:

我有一个将事件附加到表单的代码。

this.form.Resize += new EventHandler(form_Resize);

如您所见,这是由+= 完成的。 如果上面的代码被执行了两次或多次,

像这样:

this.form.Resize += new EventHandler(form_Resize);
this.form.Resize += new EventHandler(form_Resize);
this.form.Resize += new EventHandler(form_Resize);
this.form.Resize += new EventHandler(form_Resize);
this.form.Resize += new EventHandler(form_Resize);

回调方法是否被多次附加?

方法会被调用多少次 form_Resize?

如果一个事件的回调方法被多次分配给同一个对象,它会被多次执行吗?

【问题讨论】:

  • 不,我不知道。我虽然优化器会看到这个额头并且不会多次附加。

标签: c# java


【解决方案1】:

每次附加事件处理程序时都会调用一次。 (C#)

为了防止双重附件,你可以使用这个模式:

this.form.Resize -= new EventHandler(form_Resize); 
this.form.Resize += new EventHandler(form_Resize); 

如果没有附加处理程序,第一条语句将不会引发错误,并将删除现有处理程序。

【讨论】:

  • 在您的示例中,您正在创建EventHandler 的两个不同实例,因此它不会阻止您进行多次调用。您必须创建一次 EventHandler 并将其存储在局部变量中才能使其正常工作...
  • 这是不正确的。 System.Delegate 覆盖 Equals;对于事件处理程序删除代码,这两个对象是相等的,即使它们是两个不同的实例,并且如果事件处理程序已经存在,则将其删除。见msdn.microsoft.com/en-us/library/99bthb1z.aspx
【解决方案2】:

它将在 C# 中 - 我不了解 Java。您正在向同一个方法添加多个委托,每个委托都会被依次调用。

这里有一个简单的例子来证明这一点:

using System;

class Example
{
    static event Action Bar;

    static void Main()
    {
        Bar += Foo;
        Bar += Foo;

        Bar();
    }

    static void Foo()
    {
        Console.WriteLine("Foo");
    }
}

【讨论】:

  • 如何判断代理是否已经附加到事件中,以便不再附加?
  • 您需要在该事件上调用GetInvocationList 并检查是否已添加代理。这仅适用于拥有委托的类型,因此如果您不拥有公开委托的类型的源,您将无法执行此操作。
  • @Pentium10:正如 Doug 所说,您可以在 += 之前使用 -= 来删除现有的事件处理程序(如果存在)。
【解决方案3】:

调用列表中允许重复,所以是的,该方法将被执行多次。至少在 C# 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 2018-08-18
    • 2021-01-21
    • 2012-09-23
    • 1970-01-01
    相关资源
    最近更新 更多