﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>jOHN commented on Correct event handling</title><description>Ayende, 
  
  
If you lock when sending the handler than you could get a deadlock.
  
  
I am only trying to lock the value so it is not in an inconsitant state.  I am unable to find the place where I was told this in the first place.  
  
  
If I recall what I was told orginally.  You lock the varible and what you are coping from so the new value is in a know state.  Then if the handle is released after the copy/lock the original value is still valid.
  
  
If you attempt to use "handler(...)" during the call the handler could be release which would generate a error.
  
  
Regards,
  
John
</description><link>http://ayende.com/3703/correct-event-handling#comment20</link><guid>http://ayende.com/3703/correct-event-handling#comment20</guid><pubDate>Thu, 20 Nov 2008 16:43:18 GMT</pubDate></item><item><title>Cherian commented on Correct event handling</title><description>Bart,
  
    I used to use the anonymous delegate pattern.This one is a bit tricky though.  See 
[stackoverflow.com/.../is-there-a-downside-to-ad...](http://stackoverflow.com/questions/170907/is-there-a-downside-to-adding-an-anonymous-empty-delegate-on-event-declaration#264413)  
</description><link>http://ayende.com/3703/correct-event-handling#comment19</link><guid>http://ayende.com/3703/correct-event-handling#comment19</guid><pubDate>Mon, 17 Nov 2008 10:13:54 GMT</pubDate></item><item><title>Bart Czernicki commented on Correct event handling</title><description>I use the anonymous method trick I saw on DotnetKicks several months ago also its in Skeet's C# 3.0...its the same what Simon posted.
  
 handler = delegate {};
  
  
Just to add to this, this handler cannot be removed in C# 3.0.  Not sure if 4.0 changes this, but you are guaranteed that there will always be one subscriber.
  
  
</description><link>http://ayende.com/3703/correct-event-handling#comment18</link><guid>http://ayende.com/3703/correct-event-handling#comment18</guid><pubDate>Mon, 17 Nov 2008 02:30:31 GMT</pubDate></item><item><title>Andr&amp;#233;s G. Aragoneses commented on Correct event handling</title><description>The best thing to do about this is having a tool (a post-compiler) like Gendarme or FxCop that warns you about it.
  
  
For example:
  
[www.mono-project.com/Gendarme.Rules.Concurrency](http://www.mono-project.com/Gendarme.Rules.Concurrency#ProtectCallToEventDelegatesRule)</description><link>http://ayende.com/3703/correct-event-handling#comment17</link><guid>http://ayende.com/3703/correct-event-handling#comment17</guid><pubDate>Mon, 17 Nov 2008 02:16:38 GMT</pubDate></item><item><title>Liviu commented on Correct event handling</title><description>Nobody has to write that stuff. Use postsharp for god's sake...
</description><link>http://ayende.com/3703/correct-event-handling#comment16</link><guid>http://ayende.com/3703/correct-event-handling#comment16</guid><pubDate>Sun, 16 Nov 2008 19:47:32 GMT</pubDate></item><item><title>Ayende Rahien commented on Correct event handling</title><description>Rafal,
  
I write about what I do.
</description><link>http://ayende.com/3703/correct-event-handling#comment15</link><guid>http://ayende.com/3703/correct-event-handling#comment15</guid><pubDate>Sun, 16 Nov 2008 18:54:49 GMT</pubDate></item><item><title>RafalG commented on Correct event handling</title><description>Ayende, I enjoyed your posts about boo, brail, rhinos and other interesting, sophisticated, nontrivial subjects that encouraged discussion. But lately you seem to have switched to less demanding mode - short, unrelated, frequent and unsignificant stories in fire &amp; forget manner. Maybe that's because you're very busy doing real projects, but I had to point it out. Remember, quality * quantity = const, even if the const is very big.
  
  
  
</description><link>http://ayende.com/3703/correct-event-handling#comment14</link><guid>http://ayende.com/3703/correct-event-handling#comment14</guid><pubDate>Sun, 16 Nov 2008 11:27:02 GMT</pubDate></item><item><title>Krzysztof Kozmic commented on Correct event handling</title><description>You may also want to read this series of blogposts on the very same topic:
  
[blogs.msdn.com/.../92787.aspx](http://blogs.msdn.com/jaybaz_ms/archive/2004/03/19/92787.aspx)  
[blogs.msdn.com/.../158636.aspx](http://blogs.msdn.com/jaybaz_ms/archive/2004/06/17/158636.aspx)  
[blogs.msdn.com/.../230681.aspx](http://blogs.msdn.com/jaybaz_ms/archive/2004/09/16/230681.aspx)  
  
</description><link>http://ayende.com/3703/correct-event-handling#comment13</link><guid>http://ayende.com/3703/correct-event-handling#comment13</guid><pubDate>Sun, 16 Nov 2008 08:09:20 GMT</pubDate></item><item><title>Ayende Rahien commented on Correct event handling</title><description>john,
  
Event handlers are immutables, so you don't need to look them.
  
The object that you get is always in consistent state.`
</description><link>http://ayende.com/3703/correct-event-handling#comment12</link><guid>http://ayende.com/3703/correct-event-handling#comment12</guid><pubDate>Sun, 16 Nov 2008 06:20:39 GMT</pubDate></item><item><title>Simon Gillbee commented on Correct event handling</title><description>There's another solution that both makes the code simpler and solves the multi-threaded issue:
  
  
public Action
&lt;iapplicationlifecycle Completed = delegate {};
  
  
void OnCompleted ()
  
{
  
   Completed (this);
  
}
  
  
This solution works nicely in that Completed can *never* be null, and since we don't have to juggle the null-check, we don't need to worry about the multi-threaded implications (except about the subscription during invocation mentioned in an earlier comment).
  
  
There is some minor runtime overhead with this pattern, but personally I think the trade-off is worth it.
&gt;</description><link>http://ayende.com/3703/correct-event-handling#comment11</link><guid>http://ayende.com/3703/correct-event-handling#comment11</guid><pubDate>Sun, 16 Nov 2008 04:49:01 GMT</pubDate></item><item><title>alwin commented on Correct event handling</title><description>Shouldn't you use [MethodImpl(MethodImplOptions.NoInlining)] for your Raise() method? Else its possible that it isn't thread safe.
  
  
When inlining, the local variable disappears and you could get sort of
  
if (Completed != null){
  
    Completed(this);
  
}
  
Not what you want...
  
  
(Read that somewhere long ago, remembered it, googled and found 
[http://blog.quantumbitdesigns.com/tag/events/](http://blog.quantumbitdesigns.com/tag/events/) )
</description><link>http://ayende.com/3703/correct-event-handling#comment10</link><guid>http://ayende.com/3703/correct-event-handling#comment10</guid><pubDate>Sun, 16 Nov 2008 03:23:51 GMT</pubDate></item><item><title>Judah commented on Correct event handling</title><description>Oren,
  
  
You're right, an event with no subscribers should not throw when we attempt to raise the event. Poor design choice by the .NET guys.
  
  
One workaround is a simple extension method:
  
  
[stackoverflow.com/.../evil-use-of-extension-met...](http://stackoverflow.com/questions/248072/evil-use-of-extension-methods)  
  
public static void Raise(this EventHandler handler, object sender, EventArgs args)
  
{
  
   if (handler != null)
  
   {
  
      handler(sender, args);
  
   }
  
}
  
  
(And an overload for generic EventHandlers, and you're all set.)
</description><link>http://ayende.com/3703/correct-event-handling#comment9</link><guid>http://ayende.com/3703/correct-event-handling#comment9</guid><pubDate>Sun, 16 Nov 2008 01:13:46 GMT</pubDate></item><item><title>Mark Nijhof commented on Correct event handling</title><description>Ayende,
  
  
Would you keep both null checks or just the later one?
  
  
John,
  
  
Should the lock not be around the whole code block to be effective? And also around any subscribing and un-subscribing code blocks? because you are not locking the variables inside the lock, you are locking that part of the code, if I understand it correctly? Please correct me if I am wrong.
  
  
-Mark
</description><link>http://ayende.com/3703/correct-event-handling#comment8</link><guid>http://ayende.com/3703/correct-event-handling#comment8</guid><pubDate>Sun, 16 Nov 2008 00:57:48 GMT</pubDate></item><item><title>john commented on Correct event handling</title><description>I was told you should lock the value during the copy since it could change at that point.  Sorry I forgot where I read it.
  
  
static readonly object lockObject = new object();
  
lock(lockObject)
  
{
  
  handler = Completed;
  
}
  
  
if(hander != null)
  
{
  
  handler(this);
  
}
</description><link>http://ayende.com/3703/correct-event-handling#comment7</link><guid>http://ayende.com/3703/correct-event-handling#comment7</guid><pubDate>Sat, 15 Nov 2008 23:35:19 GMT</pubDate></item><item><title>Phil Murphy commented on Correct event handling</title><description>I hate to have to say it, but this seems to be one of those cases where VB.NET's behaviour is better than C# - apparently "RaiseEvent" will do the multi-threaded null checking for you. 
  
  
Apparently. I wouldn't use VB.NET myself, you understand.
</description><link>http://ayende.com/3703/correct-event-handling#comment6</link><guid>http://ayende.com/3703/correct-event-handling#comment6</guid><pubDate>Sat, 15 Nov 2008 23:25:04 GMT</pubDate></item><item><title>Russ commented on Correct event handling</title><description>There's still a threading issue, because an even is a multicast delegate. If there are two subscribers, the second could unsubscribe in another thread from Completed whilst handler is invoking the first; in which case handler will suffer an ObjectDisposedException. I'm not aware of any way to avoid it.
</description><link>http://ayende.com/3703/correct-event-handling#comment5</link><guid>http://ayende.com/3703/correct-event-handling#comment5</guid><pubDate>Sat, 15 Nov 2008 23:17:17 GMT</pubDate></item><item><title>Andrew Davey commented on Correct event handling</title><description>I use a macro in Nemerle to generate this, so all I have to type is:
  
  
raiseevent Completed(this)
  
  
:)
</description><link>http://ayende.com/3703/correct-event-handling#comment4</link><guid>http://ayende.com/3703/correct-event-handling#comment4</guid><pubDate>Sat, 15 Nov 2008 23:15:28 GMT</pubDate></item><item><title>Thomas Krause commented on Correct event handling</title><description>That's an easy one. If the other thread unsubscribes from the event after the condition has been checked, but before you assign the variable and there are no other subscribers, you'll assign a null reference and get a NullReferenceException.
</description><link>http://ayende.com/3703/correct-event-handling#comment3</link><guid>http://ayende.com/3703/correct-event-handling#comment3</guid><pubDate>Sat, 15 Nov 2008 22:43:56 GMT</pubDate></item><item><title>Peter Morris commented on Correct event handling</title><description>Stood out like a sore thumb :-)
</description><link>http://ayende.com/3703/correct-event-handling#comment2</link><guid>http://ayende.com/3703/correct-event-handling#comment2</guid><pubDate>Sat, 15 Nov 2008 22:40:07 GMT</pubDate></item><item><title>Rik Hemsley commented on Correct event handling</title><description>Just to note that R# can generate this code for you, which is handy as it's something I have to write many times a day.
  
  
</description><link>http://ayende.com/3703/correct-event-handling#comment1</link><guid>http://ayende.com/3703/correct-event-handling#comment1</guid><pubDate>Sat, 15 Nov 2008 22:13:23 GMT</pubDate></item></channel></rss>