2011-02-09 27 views
4

我有以下代码,我用它来模拟一个实时数据馈送,同时 发送一个消息,在集合“Portfolio.Symbols”内的每个对象的类型“符号”应该回应(通过另一种方法来做一些工作)。多个匿名事件处理程序 - 但只有最后一个被称为

为了它是真实的同时,我尝试注册一个匿名事件处理方式如下:

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 {}; 
... 

我再尝试引发事件,希望我会得到一个号码“的someMethod的“情况发生。不幸的是,只有最后添加的“符号”被调用。

我在这里错过了什么?

+2

只有最后一个“符号”添加被称为 - 是的,但它被称为很多。 – 2011-02-09 13:33:15

+0

参见http://stackoverflow.com/questions/3190578/from-eric-lipperts-blog-dont-close-over-the-loop-variable(以及顶部和评论中的各种链接)。这是一个非常受欢迎的SO问题。 – Brian 2011-02-09 14:23:28

回答

10

臭名昭着的捕获变量/ foreach故障;尝试:

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

and btw;静态event s是确实危险 - 这些事件订阅不会自行退订,所以您可能会在内存中不必要地留下大量内容。您可以使他们自退订,当然:

foreach (Symbol symbol in Portfolio.Symbols) 
{ 
    var copy = symbol; 
    OnGenerateQuoteRequestEventHandler handler = null; 
    handler =() => { 
     SomeMethod(copy); 
     GenerateQuoteRequest -= handler; 
    }; 
    GenerateQuoteRequest += handler; 
} 
相关问题