从EventHandler中移除EventHandler的问题

本文关键字:EventHandler 问题 | 更新日期: 2023-09-27 18:08:48

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

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

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

从EventHandler中移除EventHandler的问题

也许你的问题是你的事件的方式?您必须首先将事件背后的当前委托复制到一个局部变量,然后检查它是否为空,并且只有然后调用它。这样的:

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

确保正确地编写了事件访问器。它应该看起来像这样:

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

同时,考虑使用这个来添加事件处理程序:

otherClassObj.OnMyDataReceived += analyzeValues;

下面的应用程序演示如何订阅和取消订阅事件。您可以将此代码放入一个新的控制台应用程序中以运行它。

它显示事件第一次被引发时,您的事件处理程序被调用,然后取消订阅。第二次,不再订阅处理程序,什么也没发生。

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);
        }
    }
}