At the moment I’m writing a guide to do design review for .NET 4.0 applications writen in C#. One of the small questions I had was what to do with event handlers that use lambda expressions and closures.
The problem of closures is that by using members that are on the scope of the object defining the lambda they create references to those members and can cause unexpected leaks.
One of the things I wanted to try is to see if using the same lambda (Test1) to unsubscribe would remove it from the invocation list of the event. The answer is NO it does not. I have seen code that uses this but as this test shows it does nothing. The only way to remove it from the invocation list is to hold the reference to the lamdba in a variable and use that to subscribe and unsubscribe (Test2). The code loses the beauty of using the lamdba to shorten it and I am considering to allow only the use of lamdbas that do not use members of the object.
class Program { static void Main(string[] args) { Console.WriteLine("Test 1 : Do not hold the lambda in a variable:"); Console.WriteLine(); Test1(); Console.WriteLine("Test 2 : Hold the lambda in a variable."); Console.WriteLine(); Test2(); } private static void Test1() { EventPublisher ep = new EventPublisher(); ep.TestEvent += (o, e) => { }; Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers); ep.TestEvent -= (o, e) => { }; Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers); Console.ReadLine(); } private static void Test2() { EventPublisher ep = new EventPublisher(); EventHandler<EventArgs> t = (o, e) => { }; ep.TestEvent += t; Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers); ep.TestEvent -= t; Console.WriteLine("Number of subscribers = {0}", ep.NumberOfSubscribers); Console.ReadLine(); } } class EventPublisher { public event EventHandler<EventArgs> TestEvent; public int NumberOfSubscribers { get { if (this.TestEvent != null) { return this.TestEvent.GetInvocationList().Length; } return 0; } } public void Publish() { this.OnTestEvent(new EventArgs()); } protected virtual void OnTestEvent(EventArgs e) { if (this.TestEvent != null) { this.TestEvent(this, e); } } }
The output of this small program is the following:
Test 1 : Do not hold the lambda in a variable: Number of subscribers = 1 Number of subscribers = 1 Test 2 : Hold the lambda in a variable. Number of subscribers = 1 Number of subscribers = 0
As you can see beware of lambdas in Event Handlers.
Have fun,
29 comments:
籃子打水空費力,經驗必需靈活用。......................................................
向著星球長驅直進的人,反比踟躕在峽路上的人,更容易達到目的。............................................................
君子立恆志,小人恆立志。..................................................
婚姻對男人來說是賭他的自由,對女人而言卻是賭她的幸福。..................................................................
幸福不是一切,人還有責任。....................................................................
成熟,就是有能力適應生活中的模糊。.................................................................
成熟,就是有能力適應生活中的模糊。.................................................................
安安!剛開始玩這個,來這裡逛一下^^............................................................
人生是故事的創造與遺忘。............................................................
我真心在追求我的夢想時,每一天都是繽紛的。因為我知道每一個小時都是實現理想 的一部份。..................................................
要經常發表文章 最愛你了呦............................................................
路過留言支持~~~..................................................................
唯有用熱情、用智慧去觀察事物,這事物才會把他的秘密,洩漏給我們............................................................
只要有心,人人可以是熱門blog!!!.................................[/url]...............
做些小善事,說些愛的字句,世界更快樂。..................................................
你的努力我們都看見了--支持你............................................................
認識自己,是發現妳的真性格、掌握妳的命運、創照你前程的根源。............................................................
時時關心,時時感動。..................................................
你的部落帶給我愉快的心情,感謝~~............................................................
獨居時,要反省自己的過錯;在社會大眾之間,則要忘卻別人的過失。..................................................
道歉是人類一定必要的禮節..................................................
Practice makes perfect.............................................................
所有的資產,在不被諒解時,都成了負債.................................................................
Man proposes, God disposes..................................................................
來打聲招呼-大家好!!!............................................................
出遊不拘名勝,有景就是好的..................................................................
您的blog蠻不錯的耶,祝你快樂哦!期待您的更新!............................................................
肯定與支持你!!!加油囉~..................................................
財富並非永遠的朋友,但朋友卻是永遠的財富。......................................................................
Post a Comment