0

我的应用程序中有此代码

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

如果不调试,事件就会很好地引发并正常工作。但是,当调试并尝试更改执行步骤时,例如将执行步骤拖到另一个条件块中的 raiseevent,该事件不会触发。

我究竟做错了什么?

4

1 回答 1

2

我复制。可以说,这是调试器中的一个错误,在我看来很难修复。将代码从 vb.net 反编译为 C# 时更容易看到。此示例代码:

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

被翻译成这个等效的 C# 代码:

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);
        }
    }
}

当您使用 Set Next Statement 调试器命令将执行点设置到第二个 RaiseEvent 语句时,调试器会将执行点移动到上面代码片段中标记为 HERE 的语句。绕过临时变量的初始化。仍然为空,因此不会引发该事件。使用该命令后,您可以通过使用 Debug + Windows + Disassembly 查看机器代码来观察这种情况。

否则,这与任何 C# 程序员都非常熟悉的事件引发代码完全相同,他们没有引发事件访问器,因此必须编写以下代码:

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

好吧,调试器搞砸了,很容易看出它是如何发生的。以及它是如何一直未被发现(或被忽略)的。变通办法很难找到,在 RaiseEvent 语句之前的语句会起作用,但非常不切实际。修改变量以使 If 语句执行所需的事件是可能的。

我在 connect.microsoft.com 上报告了这个问题,反馈文章在这里。不要期待奇迹。

于 2012-06-20T11:58:27.813 回答