Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# 如何避免多次注册事件_C#_.net - Fatal编程技术网

C# 如何避免多次注册事件

C# 如何避免多次注册事件,c#,.net,C#,.net,我有一个注册事件处理程序的事件 event Action OnGameList; 例如,我得到了如下代码: backend.OnGameList += ProcessGameList; backend.GetGameList(); //this will trigger the above event. backend.OnGameList -= ProcessGameList; 每次我看到这段代码时,都会添加处理程序。这意味着第二次它将被调用两次。 当然,我可以在函数中删除它,如下所示:

我有一个注册事件处理程序的事件

event Action OnGameList;
例如,我得到了如下代码:

backend.OnGameList += ProcessGameList;
backend.GetGameList(); //this will trigger the above event.
backend.OnGameList -= ProcessGameList;
每次我看到这段代码时,都会添加处理程序。这意味着第二次它将被调用两次。 当然,我可以在函数中删除它,如下所示:

backend.OnGameList += ProcessGameList;
backend.GetGameList(); //this will trigger the above event.
backend.OnGameList -= ProcessGameList;

但是我觉得对于这种问题有更好的解决办法。

我认为您应该使用某种支持字段来跟踪您已经订阅的内容。即

    private bool _subscribed = false;

    SubscribeToOnGameListEvent();
    backend.GetGameList();

    private void SubscribeToOnGameListEvent()
    {
        if (!_subscribed)
        {
            backend.OnGameList += ProcessGameList;
            _subscribed = true;
        }
    }

我认为您应该使用某种支持字段来跟踪您已经订阅的内容。即

    private bool _subscribed = false;

    SubscribeToOnGameListEvent();
    backend.GetGameList();

    private void SubscribeToOnGameListEvent()
    {
        if (!_subscribed)
        {
            backend.OnGameList += ProcessGameList;
            _subscribed = true;
        }
    }

您可以检查调用列表中是否存在特定委托:

class Foo
{
    private EventHandler bar;

    public event EventHandler Bar
    {
        add
        {
            if (bar == null)
            {
                bar = value;
            }
            else
            {
                if (!bar.GetInvocationList().Contains(value))
                {
                    bar += value;
                }
            }
        }
        remove
        {
            // ...
        }
    }

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

您可以检查调用列表中是否存在特定委托:

class Foo
{
    private EventHandler bar;

    public event EventHandler Bar
    {
        add
        {
            if (bar == null)
            {
                bar = value;
            }
            else
            {
                if (!bar.GetInvocationList().Contains(value))
                {
                    bar += value;
                }
            }
        }
        remove
        {
            // ...
        }
    }

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

没有更多的代码很难说。显而易见的答案是在代码中只添加一次事件,而您不会重复调用该事件,但如果不理解为什么要多次添加该事件,则很难给出更具体的建议。您可以安全地先删除事件,然后再添加。否则,您必须检查它是否已经注册。我必须承认,如果我的设计只供我使用,并且我只想附加处理程序一次,即使附加例程被调用n次(比方说,每次出现自定义弹出窗口),我总是使用-=在+=之前。它从未崩溃,而且总是有帮助。Iirc.在浏览和相关页面时,Dennis的回答似乎提供了预期的语义:多次订阅单个处理程序的尝试被忽略,第一次取消订阅将删除该处理程序。如果没有更多代码,很难说。显而易见的答案是在代码中只添加一次事件,而您不会重复调用该事件,但如果不理解为什么要多次添加该事件,则很难给出更具体的建议。您可以安全地先删除事件,然后再添加。否则,您必须检查它是否已经注册。我必须承认,如果我的设计只供我使用,并且我只想附加处理程序一次,即使附加例程被调用n次(比方说,每次出现自定义弹出窗口),我总是使用-=在+=之前。它从未崩溃,而且总是有帮助。Iirc.在浏览和相关页面时,Dennis的回答似乎提供了预期的语义:多次订阅单个处理程序的尝试被忽略,第一次取消订阅将删除该处理程序。这似乎是一个很好的解决方案,但在我的特定情况下,我无法真正使用它,因为我的事件是从WCF服务引用自动生成的类。这似乎是一个很好的解决方案,但是在我的特定情况下,我不能真正使用它,因为我的事件是从WCF服务引用自动生成的类。