Welcome to McFunley.com Sign in | Join | Faq

Thread Safety in VB-2003 Events

posted on Saturday, January 15, 2005 7:10 AM by mcfunley

Brad Abrams had a recent post about how the usual way of raising an event in C#:

 

protected virtual void OnMyEvent(EventArgs e)

{

if(MyEvent != null)

      {

            MyEvent(this, e);

      }

}

 

is not threadsafe. Purely out of curiosity, I wondered if VB handles this the correct way:

 

protected virtual void OnMyEvent(EventArgs e)

{

EventHandler handler = MyEvent;

      if(handler != null)

      {

            handler(this, e);

      }

}

 

Since VB abstracts this away with the RaiseEvent keyword. Unfortunately it doesn’t seem to, as this code:

 

Protected Overridable Sub OnMyEvent(ByVal e As EventArgs)

RaiseEvent MyEvent(Me, e)

End Sub

 

Compiles to this:

 

.method family newslot virtual instance void OnMyEvent([mscorlib]System.EventArgs e) cil managed
{
      // Code Size: 22 byte(s)
      .maxstack 8
      L_0000: ldarg.0
      L_0001: ldfld [mscorlib]System.EventHandler VbConsoleApp.Test::MyEventEvent
      L_0006: brfalse.s L_0015
      L_0008: ldarg.0
      L_0009: ldfld [mscorlib]System.EventHandler VbConsoleApp.Test::MyEventEvent
      L_000e: ldarg.0
      L_000f: ldarg.1
      L_0010: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, [mscorlib]System.EventArgs)
      L_0015: ret
}

 

Which has a race condition--it should store the delegate in a local. Generally, my answer to all of these questions is “it is fixed in 2005” – so I’m going to just assume that that is the case here.

Comments

# re: Thread Safety in VB-2003 Events @ Saturday, January 15, 2005 9:44 AM

Looks like it is :-)
November CTP:
Public Event SomeEvent()
Public Sub IsItFixed()
RaiseEvent SomeEvent()
End Sub


.method public instance void IsItFixed() cil managed
{
// Code size 17 (0x11)
.maxstack 1
.locals init ([0] class WinAppVB.Form1/SomeEventEventHandler VB$t_ref$S0)
IL_0000: ldarg.0
IL_0001: ldfld class WinAppVB.Form1/SomeEventEventHandler WinAppVB.Form1::SomeEventEvent
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: callvirt instance void WinAppVB.Form1/SomeEventEventHandler::Invoke()
IL_0010: ret
} // end of method Form1::IsItFixed

  Daniel Moth

SKIN NAME : ImageHeader