Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从EventHandler中删除EventHandler时出现问题_C#_Event Handling - Fatal编程技术网

C# 从EventHandler中删除EventHandler时出现问题

C# 从EventHandler中删除EventHandler时出现问题,c#,event-handling,C#,Event Handling,我向事件中添加了一个方法,但现在希望在某些情况下将该方法从这些事件上删除: public MyClassConstructor() { otherClassObj.OnMyDataReceived += new EventHandler(analyzeValues); } private void analyzeValues(object sender, EventArgs e) { // finished analysis otherClassObj.OnMyDataR

我向事件中添加了一个方法,但现在希望在某些情况下将该方法从这些事件上删除:

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

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

请确保您的事件访问器已启用。它应该是这样的:

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

也许你的问题在于你举办活动的方式?必须首先将事件后面的当前委托复制到局部变量,然后将其检查为null,然后才调用它。像这样:

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

你说“破坏程序”是什么意思?你有例外吗?例外是什么?不,没有有用的例外。我本来可以说得更清楚的。主窗口刚刚关闭,我不再跑步。这个程序似乎已经存在了,你能展示运行这个代码的代码吗?如果您有一个控制台应用程序在引发此事件后完成,它将退出。整个程序肯定会继续运行。它太大了,现在无法在这里发布,对不起。把你自己从你自己的内心抹去有什么不对吗?我看不出你发布的代码有什么不对…@DanielMann当然有。当您添加或删除处理程序时,它通过引用来执行。如果他在没有启用调试的情况下运行它,它可能会崩溃,特别是取决于.NET的版本。@ChristopherPfohl听起来很有趣!你有更多信息的链接吗?我认为这个答案不正确。使用
+=neweventhandler(analyzeValues)
添加,然后使用
-=analyzeValues
删除,似乎效果不错。不过,上面的答案可能与注释有关,因为方法组转换语法更好。@JeppeStigNielsen这只是我的直觉。我创建了一个测试应用程序,它似乎工作得很好,尽管我不能100%确定事件绑定的内部结构。也许这与OP的代码中如何编写
onmydatareceived
的访问器有关。是的,这是可能的。尽管许多人使用所谓的类字段事件,编译器会自动生成
add
remove
访问器。+1这也是一个潜在的问题。当然,使用提供的代码很难判断。