2012-03-01 27 views
7

我有这样的代码:设置一个事件为Null

public class SomeClass 
{ 
    int _processProgress; 
    public int ProcessProgress 
    { 
     get { return _processProgress; } 
     set 
     { 
      _processProgress = value; 
      if (ProcessProgressChanged != null) 
       ProcessProgressChanged(value); 
     } 
    } 

    public delegate void ProcessProgressChangedEventHandler(int progressPercentage); 
    public event ProcessProgressChangedEventHandler ProcessProgressChanged; 

    public void ClearProcessProgressChangedEvent() 
    { 
     this.ProcessProgressChanged = null; 
    } 
} 

请问它退订ProcessProgressChanged事件,当我称之为ClearProcessProgressChangedEvent()方法所有的方法?

我的代码是在C#中,框架4,构建在VS2010 Pro中,项目在Winforms中。

请帮助。提前致谢。

+2

此问题不重复。在那个问题中,他们询问如何将对象注册为空 - 即注册到事件中。他们询问有关将事件本身设置为空的问题。 – Wes 2017-02-22 15:30:51

回答

14

那么,它将有效地清除用户列表,是的(通过将底层委托字段设置为null) - 以便下次设置ProcessProgress时,不会调用任何处理程序。这并不是真的将事件设置为null - 它将底层字段设置为null。只是C#编译器使用单个声明创建事件(订阅/取消订阅方法对)和字段(存储处理程序)。

您可能会发现我的article about events and delegates有用。

请注意,您的事件提升代码当前不是线程安全的。我不知道是否必须或没有,但你可能要使用到考虑

set 
{ 
    _processProgress = value; 
    var handlers = ProcessProgressChanged; 
    if (handlers != null) 
    { 
     handlers(value); 
    } 
} 

这样,你不会得到一个NullReferenceException如果最后的处理程序是退订在法律上无效后检查之前的调用。

+1

谢谢,再次感谢_thread-safe tip_。 – 2012-03-01 09:15:18

+0

乔恩,你会碰巧知道如果订阅匿名代理到事件,然后通过将事件分配给null来清除事件可以防止垃圾收集在例如lambda表达式中引用的对象上? – Apelsin 2013-05-18 02:40:06

+1

@Apelsin:你必须举一个更具体的例子,说实话 - 可能是一个新的问题。但是如果事件的基础字段设置为空,我看不到会阻止垃圾回收。 – 2013-05-18 06:59:19

3

是的,它会取消订阅活动中的所有人。有一个(有点间接恕我直言)参照本here

当所有用户都从事件退订,在发布类的事件 实例设置为null