Martin
Martin

Reputation: 1536

RaiseEvent when debugging and changing execution step

I have this code in my application

If _oCurrentCall.CustomData.Length > 0 AndAlso UsageType = UsageTypeEnum.Vanlig Then
  RaiseEvent NewIncomingCallWithCustomData(_oCurrentCall)
ElseIf UsageType = UsageTypeEnum.Sentralbord Then
  RaiseEvent NewIncomingCall(_oCurrentCall, Queues)
End If

Without debugging the events are raised just fine and working. However, when debugging and trying to change execution step like dragging the execution step to the raiseevent in the other condition block, the event doesn't fire.

What am I doing wrong?

Upvotes: 0

Views: 691

Answers (1)

Hans Passant
Hans Passant

Reputation: 942000

I repro. This is, arguably, a bug in the debugger, it looks very hard to fix to me. It is easier to see when decompiling the code from vb.net to C#. This sample code:

Class Test
    Public Event Foo As EventHandler
    Public Event Bar As EventHandler

    Public Sub Run(ByVal arg As Integer)
        If arg = 0 Then
            RaiseEvent Foo(Me, EventArgs.Empty)
        Else
            RaiseEvent Bar(Me, EventArgs.Empty)
        End If
    End Sub
End Class

Gets translated to this equivalent C# code:

public void Run(int arg)
{
    EventHandler VB$t_ref$S0;
    if (arg == 0)
    {
        VB$t_ref$S0 = this.FooEvent;
        if (VB$t_ref$S0 != null)
        {
            VB$t_ref$S0(this, EventArgs.Empty);
        }
    }
    else
    {
        VB$t_ref$S0 = this.BarEvent;
        if (VB$t_ref$S0 != null)              // <=== HERE!!!
        {
            VB$t_ref$S0(this, EventArgs.Empty);
        }
    }
}

When you use the Set Next Statement debugger command to set the execution point to the second RaiseEvent statement, the debugger moves the execution point to the statement marked by HERE in the above snippet. Bypassing the initialization of the temporary variable. Which is still null so the event won't be raised. You can observe this happening by looking at the machine code with Debug + Windows + Disassembly after using the command.

This is otherwise the exact same kind of event raising code that's very familiar to any C# programmer, they don't have the raise event accessor so have to write this:

var temp = Bar;
if (temp != null) {
    Bar(this, EventArgs.Empty);
}

Well, the debugger fumbles this, it is easy to see how it could happen. And how it could have gone on undetected (or ignored) for so long. Workarounds are hard to come by, a statement before the RaiseEvent statement would work but is very impractical. Modifying the variable(s) so that the If statement executes the desired event is possible.

I reported the issue at connect.microsoft.com, feedback article is here. Don't expect miracles.

Upvotes: 2

Related Questions