Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple anonymous event handlers - but only last one is called

Tags:

c#

.net

events

I have the following code I use to simulate a live data feed which simultaneously sends a message that each object of type "Symbol" in the collection inside "Portfolio.Symbols" should respond to (by another method doing some work on it).

In order for it to be true simultaneously, I try to register an anonymous event handlers the following way:

static public void RegisterEvents()
{
   foreach (Symbol symbol in Portfolio.Symbols)
   {
      GenerateQuoteRequest += () => { SomeMethod(symbol); };
   }
}

static public void Run()
{
   OnGenerateQuoteRequest();
   Thread.Sleep(100);
}

public delegate void OnGenerateQuoteRequestEventHandler();     
public static event OnGenerateQuoteRequestEventHandler GenerateQuoteRequest 
                                            = delegate {};
...

I then try to raise the event, hoping the I will get a number of "SomeMethod" instances firing up. Unfortunately, only the last "symbol" added is called.

What am I missing here?

like image 411
Saul Avatar asked Dec 28 '22 01:12

Saul


1 Answers

The infamous captured-variable/foreach glitch; try:

foreach (Symbol symbol in Portfolio.Symbols)
{
     var copy = symbol;
     GenerateQuoteRequest += () => { SomeMethod(copy); };
}

and btw; static events are really dangerous - those event subscriptions won't unsubscribe themselves, so you could be keeping lots of things in memory unnecessarily. You can make them self-unsubscribing, of course:

foreach (Symbol symbol in Portfolio.Symbols)
{
     var copy = symbol;
     OnGenerateQuoteRequestEventHandler handler = null;
     handler = () => {
         SomeMethod(copy);
         GenerateQuoteRequest -= handler;
     };
     GenerateQuoteRequest += handler;
}
like image 64
Marc Gravell Avatar answered Jan 15 '23 22:01

Marc Gravell