onevent Code Snippet


When raising events, the .NET framework design guidelines recommend that this is done from a protected virtual method named On<EventName> (unless the class is sealed or the event is static, etc.). This leads to a recurring pattern of similarly looking code like this:


protected virtual void OnMyEvent(MyEventArgs e)
{
    if (this.MyEvent != null)
    {
        this.MyEvent(this, e);
    }
}

After having done this numerous times it struck me as a good candidate for a code snippet, so I decided to create the onevent code snippet. Creating a code snippet is pretty easy; from my decision to create the snippet to using it for the first time, I spent less than half an hour. Here’s how:


Create a new XML file. For the onevent code snippet, the contents look like this:


<?xml version=1.0 encoding=utf-8 ?>
<CodeSnippets  xmlns=http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet>
    <CodeSnippet Format=1.0.0>
        <Header>
            <Title>onevent</Title>
            <Shortcut>onevent</Shortcut>
            <Description>Code snippet for creating a method for raising an event</Description>
            <Author>Mark Seemann</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>event</ID>
                    <ToolTip>The event to raise</ToolTip>
                    <Default>Event</Default>
                </Literal>
                <Literal>
                    <ID>eventargs</ID>
                    <ToolTip>The type of event args for the event</ToolTip>
                    <Default>EventArgs</Default>
                </Literal>
            </Declarations>
            <Code Language=csharp><![CDATA[protected virtual void On$event$($eventargs$ e)
    {
        if (this.$event$ != null)
        {
            this.$event$(this, e);
        }
    }]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

Each snippet consists of a header and the snippet itself. The header mostly contains metadata like the title, the shortcut used in the code editor, etc. The only vaguely puzzling element is the SnippetTypes element, where you must specify the type of code snippet. Expansion just indicates that the code snippet will be inserted at the current location of the cursor (see the Code Snippet Schema Reference at http://msdn2.microsoft.com/en-us/library/ms171418.aspx for a full description of the possible values).


The Snippet section of the XML file consists of a Declarations section and the actual code for the snippet. Declarations is used to specify the placeholders for your code expressions – in this case, the name of the event, and the type of the event args.


The actual code is defined in a CDATA section, where each declaration is referenced by its name pre- and postfixed with $.


To start using the code snippet, just save the XML file with the .snippet extension to the C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\1033\Visual C# folder and type onevent followed by the Tab key in your code editor. Visual Studio picks up the new code snippet immediately, so you don’t even have to restart the IDE!


Obviously, you need to have already defined the EventArgs class and the event itself, but with this in place you now have an instant event raiser method, which follows the framework design guidelines.


Update: Several people have been so kind to point out to me that my code is not thread-safe (see the comments to this post). For that, I humbly apologize. In a new comment, I’ve posted the updated XML for the code snippet, including the thread-safe code.


Additionally, I have also included the updated snippet as an attachment to the post, so now you can just download the file to your C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\1033\Visual C# folder to begin using it.

onevent.snippet

Comments (10)

  1. a. says:

    this mode of event invokation is not thread safe. it’s possible to null the event handler between the ‘if’ and the real invokation.

    use this:

    EventHandlerType e = this.EventHandler;

    if (e != null)

     e(…);

  2. ploeh says:

    You are right, it’s certainly not thread-safe. The beauty of code snippets, however, is that they are open, so if you generally think this code snippet is useful, but you want to use your own coding style instead of mine, you can easily edit the snippet.

    However, I’m not going to change this particular snippet myself:

    First of all, instance method in the framework are typically not designed to be thread-safe; thread-safety is the responsibility of high-level code (one of many good points in this excellent article: http://msdn.microsoft.com/msdnmag/issues/05/08/Concurrency/), so I typically don’t need to make my event raiser method thread-safe either.

    Secondly, although I’m no expert in threading, I’m not convinced that your syntax is more thread-safe. An EventHandler is basically just another type: It’s not a value type, so when you assign the local e variable in your example, you are just passing a pointer (I think). As far as I can tell, it’s still possible for that pointer to become null between the conditional and the invokation.

    As I said, I’m no expert in threading, and if, for instance, delegates are assigned by value like value types, the above argument doesn’t hold.

    In any case, my first argument is good enough for me, but feel free to use my code snippet as a starting point for creating one exactly the way you want it to be.

  3. Mihailik says:

    Excuse me, but such code snippet ALREADY EXISTS!

    And it is thread safe. By the way, I was participating in enhancing it at beta phase.

    The snippet has name "invoke".

    Also, note that second way is definitely thread-safe. Pointer cannot became null here.

  4. ploeh says:

    Oleg, thanks for pointing out the invoke method, which I wasn’t aware of.

    This snippet provides part of the functionality of the onevent snippet, but doesn’t wrap the event invokation in a protected virtual method. It was actually that part (the method signature, and conformance to the framework design guidelines) that interested me, more than the actual implementation of the event raising code. The invoke snippet doesn’t create the method itself, whereas the onevent snippet does.

    As I wrote: I’m no expert in threading, and it would seem I’m wrong about the thread-safety issue. However, I always want to learn, so could you perhaps explain to me why the pointer cannot become null between the conditional and the invokation?

  5. Kost says:

    Memory allocated on the stack, as is the case with ‘e’, can not be modified by another thread (or process). The ‘this’ pointer lives on the heap, that is the shared memory space, and can as such be modified by other threads. If you had put a lock around the if-block it would work as well.

  6. ploeh says:

    Hi Karsten

    Thank you for joining the discussion 🙂

    We are getting a bit closer to my original disclaimer about delegates behaving like value types… What I still don’t understand (completely) is why the EventHandler would be allocated on the stack?

    This is probably just due to lack of knowledge on my part: I know that value types live on the stack; a value type is just a special kind of type that is characterized by being allocated on the stack instead of on the heap. A delegate is also a rather special kind of type – are they also, by definition, allocated on the stack?

  7. Mihailik says:

    Ploeh,

    the allocation on stack is not about EventHandler, but reference itself. The reference is on stack, but it point to heap-allocated object EventHandler.

    Such story is always in place when we see local variable to reference type. Variable itself is on stack (obviously) but it points to some object on heap.

    So, the reference itself cannot be modified in this example. Because reference lives in pure local storage — stack. No other code can modify the variable value. Other code may modify fields of same objects, and that lead to non-actual value of local variable. But nobodey can change local variable, only method itself.

    This method of handling thread-safety is very well and recommended. You grab some state BEFORE ACTUAL OPERATING in private storage like stack, and then operate on it without any worrying about threading issues. By the way, such method does not apply any performance penalty and is free from deadlock problems.

    P.S. I agree that invoke is not equal to your solution. There are many places where such additional code snippets would be very useful. It seems VS developers had no time to complete code snippet library to date of release.



    Oleg Mihailik, Developer Security MVP

    Kyiv, Ukraine

  8. ploeh says:

    Oleg, thank you for the clarification – I didn’t know that local variables are allocated on the stack (even if they point to objects on the heap), but now I do 🙂

    I’m happy I just learned something new today, and this method of creating a local variable at the beginning of some operation is a good trick to know.

    I agree that the onevent code snippet should include this extra step, and I’ll definitely be updating my local copy (however, I’m not going to change the blog post itself, since that would make this whole discussion rather meaningless).

  9. ploeh says:

    For those who are interested, here’s the updated, thread-safe code snippet:

    <?xml version=1.0 encoding=utf-8 ?>
    <CodeSnippets  xmlns=http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet>
        <CodeSnippet Format=1.0.0>
            <Header>
                <Title>onevent</Title>
                <Shortcut>onevent</Shortcut>
                <Description>Code snippet for creating a method for raising an event</Description>
                <Author>Mark Seemann</Author>
                <SnippetTypes>
                    <SnippetType>Expansion</SnippetType>
                </SnippetTypes>
            </Header>
            <Snippet>
                <Declarations>
                    <Literal>
                        <ID>event</ID>
                        <ToolTip>The event to raise</ToolTip>
                        <Default>Event</Default>
                    </Literal>
                    <Literal>
                        <ID>eventargs</ID>
                        <ToolTip>The type of event args for the event</ToolTip>
                        <Default>EventArgs</Default>
                    </Literal>
                </Declarations>
                <Code Language=csharp><![CDATA[protected virtual void On$event$($eventargs$ e)
        {
            EventHandler<$eventargs$> handler = this.$event$;
            if (handler != null)
            {
                handler(this, e);
            }
        }]]>
                </Code>
            </Snippet>
        </CodeSnippet>
    </CodeSnippets>

  10. ploeh blog says:

    So, a couple of days ago I discovered just how easy it is to create code snippets for Visual Studio 2005,…