- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
一位同事在他的 VB.net 解决方案中发现了一个有线调试器行为。我承认这将是一个更学术的问题,因为这只会影响调试时突出显示的语句的顺序,而不影响代码的整体行为。所以对于所有好奇的人:
我们将其简化为以下最小控制台应用程序:
Private Sub PlayWithExceptions
Dim a = 2
Try
throw new Exception("1")
Catch ex As Exception
If a = 2 Then
Dim x = New XElement("Dummy")
Else
throw
End If
End Try
End Sub
Sub Main()
Try
PlayWithExceptions()
Catch ex As Exception
End Try
End Sub
很明显,调试器抛出 Exception(“1”) 并且调试器跳转到 PlayWithExceptions 方法的 catch 子句。在那里,因为“a”总是 2,调试器跳转到一些伪代码(New XElement…),从那里跳到“End If”,最后回到 Else-leaf 到 throw 语句上 .我承认 Visual Studio 不会重新抛出异常,但它看起来很奇怪。
将条件“If a = 2”更改为“If True”可消除此行为。
重构为条件捕获也消除了这种行为。
Private Sub PlayWithExceptions
Dim a = 2
Try
throw new Exception("1")
Catch ex As Exception When a = 2
Dim x = New XElement("Dummy")
Catch ex As Exception
throw
End Try
End sub
将这几行翻译成 C# 也不会显示此行为。
private static void PlayWithExceptions()
{
var a = 2;
try
{
throw new Exception("1");
}
catch (Exception)
{
if (a == 2)
{
var x = new XElement("Dummy");
}
else
{
throw;
}
}
}
static void Main(string[] args)
{
try
{
PlayWithExceptions();
}
catch (Exception ex)
{
}
}
我们尝试了 .Net3.5 和 .Net4.6 以及目标 AnyCPU 和 x86,但对上述 VB 代码没有任何影响。代码是使用默认调试设置执行的,没有进一步优化。我们使用 VS2015 Update 3。
有谁知道为什么 Visual Studio 假装在 VB 中重新抛出异常(但实际上并没有重新抛出它)?调试时看起来很困惑……
最佳答案
它与为 VB.Net 的 Err
对象设置/取消设置错误信息的隐藏代码有关——它在源代码中没有真正的“位置”。
在 IL 中,清除错误的代码紧接在 rethrow
调用之后,因此这是它在即将调用它时可以显示的最近的源代码行。我无法回答的是为什么它应该在(可见的)源代码行之间步进时在调用它之前停止。
但是如果当调试器在 Throw
行时检查 Err
对象,您会看到它有一个当前异常对象。而在那之后的步骤中,当前异常已被清除。请参阅下面的 IL_0035
,了解调试器暂停的位置:
.method private static void PlayWithExceptions() cil managed
{
// Code size 62 (0x3e)
.maxstack 2
.locals init ([0] int32 a,
[1] class [mscorlib]System.Exception ex,
[2] bool V_2,
[3] class [System.Xml.Linq]System.Xml.Linq.XElement x)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
.try
{
IL_0003: nop
IL_0004: ldstr "1"
IL_0009: newobj instance void [mscorlib]System.Exception::.ctor(string)
IL_000e: throw
} // end .try
catch [mscorlib]System.Exception
{
IL_000f: dup
IL_0010: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception)
IL_0015: stloc.1
IL_0016: nop
IL_0017: ldloc.0
IL_0018: ldc.i4.2
IL_0019: ceq
IL_001b: stloc.2
IL_001c: ldloc.2
IL_001d: brfalse.s IL_0032
IL_001f: ldstr "Dummy"
IL_0024: call class [System.Xml.Linq]System.Xml.Linq.XName [System.Xml.Linq]System.Xml.Linq.XName::op_Implicit(string)
IL_0029: newobj instance void [System.Xml.Linq]System.Xml.Linq.XElement::.ctor(class [System.Xml.Linq]System.Xml.Linq.XName)
IL_002e: stloc.3
IL_002f: nop
IL_0030: br.s IL_0035
IL_0032: nop
IL_0033: rethrow
//Debugger is pausing at IL_0035 when the highlight is on Throw
IL_0035: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_003a: leave.s IL_003c
} // end handler
IL_003c: nop
IL_003d: ret
} // end of method Module1::PlayWithExceptions
对于 If True
变体,它甚至不再包含 Throw
代码,因此它显然永远不会相信它即将执行它。对于带有异常过滤器的变体,每个 Catch
子句独立管理它的 SetProjectError
/ClearProjectError
调用,因此没有混淆在调用 Throw
和调用 New XElement
之间。
关于c# - VB.net 中奇怪的调试器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40108593/
我有几个问题。我是 Visual Basic 这个领域的新手,所以不要取笑我。 1.) VB.NET之间有什么区别和 VB ? 2.) 我需要为 Windows 开发基本的应用程序。(如记事本)我应该
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是框架 3.5 的新手。我注意到,在创建 Web 内容表单时,除了 aspx.vb 页面之外,它还会创建一个 aspx.designer.vb 页面。谁能向我解释一下它们之间的区别以及它们的用途吗?
我只是想知道 VB.NET 和 VB 2010 是否相同。 我只是想知道。 最佳答案 VB 2010 是 VB.Net 的最新版本。 Microsoft 在 VB 2005 版本中删除了 VB 的“.
我是框架 3.5 的新手。我注意到,在创建 Web 内容表单时,除了 aspx.vb 页面之外,它还会创建一个 aspx.designer.vb 页面。谁能向我解释一下它们之间的区别以及它们的用途吗?
我正在尝试将 VB 函数移植到 VB.NET,但我无法使该函数正常工作并正确更新。 rFormat = Format(Format(Value, fmt), String$(Len(fmt), "@"
如何在VB中注释多行代码/代码块? 最佳答案 VB 在语言级别上没有这样的构造。它有使用撇号字符的单行注释: ' hello world ' this is a comment Rem this is
我正在使用我在 VB2005 中创建的表单在按下按钮时打开程序,然后在文本字段中显示进程 ID(再次按下按钮时)。当我运行它时,表单将打开程序 (Notepad.exe) 但当我单击按钮查看进程 ID
我正在尝试添加一个从 vb.net 创建的 dll,并且想将其导入到现有的 vb 6 项目中,但它给了我错误“无法添加对指定文件的引用”。 。有人知道如何解决这个问题吗? 最佳答案 需要遵循以下步骤:
我有一个数据 GridView 。右键单击它会显示一个上下文菜单,但它始终位于右上角。我想要它,以便菜单出现在用户右键单击的单元格上。它可能是单元格 1 或单元格 2 或其他。 谢谢福尔坎 最佳答案
我只是在 Visual Studio 2010 中使用 Visual Basic。有人知道我将如何制作“浏览文件夹(或文件)”按钮吗?我对 VB 真的很陌生,我只是在寻找一些简单的帮助:) 最佳答案
这次感到困惑... 最简单的代码行有时可能起作用,有时却没有。首先,我认为问题在于我试图读取DWORD的值,但是由于我可以从某些键读取DWORD值,所以这一定不是问题。现在的问题似乎是,如果 key
我的代码中有此方法: Private Sub Display() Received.AppendText(" - " & RXArray) End Sub 这两个调用之间有什么区别:
我正在创建一个宏程序来记录和回放鼠标和键盘输入。录制效果很好,鼠标播放也一样,但是我在播放键盘输入时遇到了麻烦——特别是在释放之前按住一个键几秒钟。这不等同于重复按键。这是我尝试过的: 技巧 1:Me
我最近刚刚了解了 VB.NET 中静态局部变量的使用,并想知道它在延迟加载属性中的潜在用途。 考虑以下示例代码。 Public Class Foo Implements IFoo End Clas
VB 有一个 C# 没有的特性,在项目级别导入命名空间(我的项目>引用>导入命名空间)。当新人在源代码控制之外检查项目时,我们的自定义导入不包括在内。这个 VB 特定的导入命名空间存储在哪里? 最佳答
我已将我的问题缩小到这个简单的案例,但似乎无法找到发生了什么: 我有两个表单,一个只有一个按钮,另一个是空的。 单击按钮时,form1 隐藏和显示 form2 出现时,form2隐藏,form1再次显
为什么下面的简单代码会失败?无论我使用 LinearGradientMode 的哪个值,这段代码总是用从左到右的渐变填充路径。 graphPath 是在别处创建的 GraphicPath 对象(基本上
我可以多快替换字符串中的字符? 所以这个问题的背景是这样的:我们有几个应用程序通过套接字相互通信并与客户端的应用程序通信。这些套接字消息包含不可打印的字符(例如 chr(0)),需要用预定的字符串(例
如何从任何文件中读取原始字节数组... Dim bytes() as Byte ..然后将该字节数组写回新文件? 我需要它作为一个字节数组来做一些处理。 我目前正在使用: 阅读 Dim fInfo
我是一名优秀的程序员,十分优秀!