从EventHandler中删除EventHandler的问题

时间:2013-04-12 18:23:54

标签: c# event-handling

我为一个事件添加了一个方法,但现在想要在某些条件之后删除该方法在这些事件上运行:

public MyClassConstructor()
{
    otherClassObj.OnMyDataReceived += new EventHandler(analyzeValues);
}
private void analyzeValues(object sender, EventArgs e)
{
    // finished analysis
    otherClassObj.OnMyDataReceived -= analyzeValues;
}

这似乎是程序崩溃,但我不明白为什么。这是我的第一个C#程序。感谢。

3 个答案:

答案 0 :(得分:2)

确保您的事件访问者为written aproprately。看起来应该是这样的:

private EventHandler onMyDataReceived;
public event EventHandler OnMyDataReceived
{
    add
    {
        lock (OnMyDataReceived)
        {
            onMyDataReceived += value;
        }
    }
    remove
    {
        lock (OnMyDataReceived)
        {
            onMyDataReceived -= value;
        }
    }
}

另外,请考虑使用它来添加事件处理程序:

otherClassObj.OnMyDataReceived += analyzeValues;

答案 1 :(得分:2)

也许你的问题是你举办活动的方式?您必须首先将事件后面的当前委托复制到本地变量,然后将其check为null,并且只有然后才会调用它。像这样:

var omdr = OnMyDataReceived;
if (omdr != null)
    omdr(this, new EventArgs());

答案 2 :(得分:1)

以下应用程序演示了如何订阅和取消订阅活动。您可以将此代码放在新的控制台应用程序中以运行它。

它表明第一次引发事件时,会调用事件处理程序,然后取消订阅。第二次,没有处理程序订阅了,没有任何反应。

using System;
class Program
{

    static void Main(string[] args)
    {
        MyClass c = new MyClass();
        Console.WriteLine("Ready..");
        Console.ReadLine();
    }
}

public class MyClass
{
    OtherClass otherClassObj = new OtherClass();

    public MyClass()
    {
        Console.WriteLine("Class constructor.. adding event");
        otherClassObj.OnMyDataReceived += analyzeValues;

        Console.WriteLine("Raising event 1");
        otherClassObj.Raise();

        Console.WriteLine("Raising event 2");
        otherClassObj.Raise();
    }

    private void analyzeValues(object sender, EventArgs e)
    {
        Console.WriteLine("Event handler");
        Console.WriteLine("Removing event");
        otherClassObj.OnMyDataReceived -= analyzeValues;
    }
}

public class OtherClass
{
    public event EventHandler OnMyDataReceived;

    public void Raise()
    {
        if (OnMyDataReceived != null)
        {
            OnMyDataReceived(this, EventArgs.Empty);
        }
    }
}