Below is my code, first is where I raise the event and second section is where I consume it in another class. It seems pretty straight forward, but the logs are showing that even though the event is raised once, the event is firing 20+ times on the class that consumes this event. Any ideas?
IBSerialPort
class:
public delegate void PacketReceivedHandler(object sender, PacketReceivedEventArgs e);
public event PacketReceivedHandler OnPacketReceived;
public class PacketReceivedEventArgs : EventArgs
{
public Packet PacketReceived { get; private set; }
public PacketReceivedEventArgs(Packet packet)
{
PacketReceived = packet;
}
}
// raise event
if (OnPacketReceived != null)
{
Log("This is only called ONCE!");
PacketReceivedEventArgs args = new PacketReceivedEventArgs(data);
OnPacketReceived(this, args);
}
Class that uses IBSerialPort
and consumes its OnPacketReceived
Event:
IBSerialPort ibSerialPort = null;
..
if (ibSerialPort == null)
{
Log("This is only called once");
ibSerialPort = IBSerialPort.Instance;
ibSerialPort.OnPacketReceived += ibSerialPort_OnPacketReceived;
}
void ibSerialPort_OnPacketReceived(object sender, IBSerialPort.PacketReceivedEventArgs args)
{
Log("This is called ~25 times!!!!");
}
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: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:
This should be done before you lose your handle to your subscriber (i.e. before
s
is out of scope ornull
). You could consider keeping track of your event source in the subsriber, and have aDispose
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.
How many times is this being called? If this gets called multiple times then your event will be called multiple times.
As a test, you could remove the delegate just before you add it:
I had the same problem, register your event in a synchronous method ( I put it in form_loaded)
Try this, this will unregister any prev subscriber: