c# event handler is called multiple times when event is raised once

穿精又带淫゛_ 提交于 2019-12-01 03:46:39

Try this, this will unregister any prev subscriber:

ibSerialPort.OnPacketReceived -= ibSerialPort_OnPacketReceived;   // unregister
ibSerialPort.OnPacketReceived += ibSerialPort_OnPacketReceived;  //register

How many times is this being called? If this gets called multiple times then your event will be called multiple times.

 ibSerialPort.OnPacketReceived += ibSerialPort_OnPacketReceived;

As a test, you could remove the delegate just before you add it:

ibSerialPort.OnPacketReceived -= ibSerialPort_OnPacketReceived;
ibSerialPort.OnPacketReceived += ibSerialPort_OnPacketReceived;

I wonder if your class that defines ibSerialPort_OnPacketReceived is used (even in separated instances) 25 times and you think you are releasing it. Consider this code:

class EventSender
{
    public Action MyEvent;
}

class Subscriber
{
    public void OnEvent()
    {
        Console.WriteLine("OnEvent");
    }
}

class Program
{
    static void Main(string[] args)
    {
        EventSender es = new EventSender();

        Subscriber s = new Subscriber();
        es.MyEvent += s.OnEvent;

        s = new Subscriber();
        es.MyEvent += s.OnEvent;

        es.MyEvent();

        Console.ReadKey();
    }
}

Here, "OnEvent" will be printed twice. A reference to the subscription is held even though it appears I've released the handle to it. This is due to how delegates keep a list of their subscribers.

If this is the problem, you'll need to unsubscribe each time:

es.MyEvent -= s.OnEvent

This should be done before you lose your handle to your subscriber (i.e. before s is out of scope or null). You could consider keeping track of your event source in the subsriber, and have a Dispose method that unsubscribes for you.

Also, as others have noted, you could unsubscribe before subscribing :) I'm sure by now you have the solution you need.

I had the same problem, register your event in a synchronous method ( I put it in form_loaded)

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        RefreshHierarchy.COIDConflict += RefreshHierarchy_COIDConflict;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!