Tuesday, June 1, 2010

Lambdas as EventHandlers

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:

韋于倫成 said...

籃子打水空費力,經驗必需靈活用。......................................................

佩GailBohanan1蓉 said...

向著星球長驅直進的人,反比踟躕在峽路上的人,更容易達到目的。............................................................

瓊文TamMcfee0520 said...

君子立恆志,小人恆立志。..................................................

亦妮亦妮 said...

婚姻對男人來說是賭他的自由,對女人而言卻是賭她的幸福。..................................................................

瑞尹 said...

幸福不是一切,人還有責任。....................................................................

KrisMcmillen07星美 said...

成熟,就是有能力適應生活中的模糊。.................................................................

秋娥秋娥 said...

成熟,就是有能力適應生活中的模糊。.................................................................

翰豪翰豪翰豪 said...

安安!剛開始玩這個,來這裡逛一下^^............................................................

JasonBirk佳琪 said...

人生是故事的創造與遺忘。............................................................

ju吳phe宇te佳ns said...

我真心在追求我的夢想時,每一天都是繽紛的。因為我知道每一個小時都是實現理想 的一部份。..................................................

義珊義珊 said...

要經常發表文章 最愛你了呦............................................................

陳博鈞陳博鈞 said...

路過留言支持~~~..................................................................

亦妮亦妮 said...

唯有用熱情、用智慧去觀察事物,這事物才會把他的秘密,洩漏給我們............................................................

李宗蓮李宗蓮 said...

只要有心,人人可以是熱門blog!!!.................................[/url]...............

楊儀卉 said...

做些小善事,說些愛的字句,世界更快樂。..................................................

dawsonfelicia張君dawsonfelicia均 said...

你的努力我們都看見了--支持你............................................................

陳晏李秀樺雄 said...

認識自己,是發現妳的真性格、掌握妳的命運、創照你前程的根源。............................................................

曹初帆張武茜 said...

時時關心,時時感動。..................................................

施以王雅玲音 said...

你的部落帶給我愉快的心情,感謝~~............................................................

家唐銘 said...

獨居時,要反省自己的過錯;在社會大眾之間,則要忘卻別人的過失。..................................................

偉曹琬 said...

道歉是人類一定必要的禮節..................................................

高黃吉軍向婷 said...

Practice makes perfect.............................................................

陳吳孟木吳孟木湘枝 said...

所有的資產,在不被諒解時,都成了負債.................................................................

孫邦柔 said...

Man proposes, God disposes..................................................................

/798 said...

來打聲招呼-大家好!!!............................................................

張王雅竹欣虹 said...

出遊不拘名勝,有景就是好的..................................................................

幸平平平平杰 said...

您的blog蠻不錯的耶,祝你快樂哦!期待您的更新!............................................................

王辛江淑萍康 said...

肯定與支持你!!!加油囉~..................................................

骆雨康 said...

財富並非永遠的朋友,但朋友卻是永遠的財富。......................................................................