调试器未捕获异步异常

时间:2014-04-18 15:10:54

标签: exception visual-studio-2013 async-await visual-studio-debugging

我正在VS2013中开展MVC5项目。我似乎发现调试器忽略了大多数(但不是全部)我的异常,因此我最终将异常和堆栈跟踪简单地写入浏览器,从而排除了对所涉及的对象的任何检查。异常。

例如 - 我故意编写一个例外来证明这一点:

    <Authorize(Roles:="IdentityAdmin")>
Public Async Function Import(model As RegisterViewModel) As Task(Of ActionResult)
    Dim a As Object = "he"
    Dim b As Integer = a

显然,最后一行会引发类型不匹配&#39;我认为应该导致调试器暂停执行的异常,突出显示VS2013 UI中的错误,使我能够检查各种对象并确定问题。

相反,我只是发现自己在浏览器中详细说明了异常并且VS2013没有响应:

  

&#39; /&#39;中的服务器错误应用

     

输入字符串的格式不正确。

     

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.FormatException:输入字符串不在   格式正确。

     

来源错误:

     

第291行:如果Db.Users.Find(acct.username)是Nothing那么

     

第292行:将As对象变暗=&#34;他&#34;

     

第293行:Dim b As Integer = a

当我将相同的异常生成代码插入到代码的非异步部分时,VS调试器捕获异常 - 所以我猜这是调试异步代码的问题。是否确实VS调试器无法捕获这些异常?

更新

进一步搜索后,我发现了一项禁用“仅限我的代码”的建议。并手动启用各种类型的异常。有一个预期的第一次机会异常的冰雹,其中大多数我可以通过禁用某些例外来调整。但是这个 DID &#39;修复了&#39;上面描述的行为。似乎调试器将我的孩子的异步线程视为“不是我的代码”。有点困惑,但我想这可能是一种答案吗?

2 个答案:

答案 0 :(得分:2)

根据上述更新,问题中详述的问题行为似乎可以通过以下方式解决:

  • 在调试器选项中关闭“Just My Code”。
  • 在Debug / Exceptions中启用某些类别的异常.. - 在我的案例中,Common Language Runtime Exceptions和Managed Debugging Assistants似乎确保调试器捕获了我的所有异常(异步或其他)。
  • 禁用抛出(但不起眼)的异常导致最悲伤(错误的全球化等)。

最后两个阶段是通过反复试验发生的,我怀疑在清理项目时我最终应该追逐大部分非破坏性异常。

答案 1 :(得分:1)

在这种情况下禁用“仅我的代码”应该没有区别,启用“抛出异常时中断”是您希望调试器停在正确位置的内容。

问题在于,当您创建方法Async时,它在后台任务中运行。任务将捕获它正在执行的代码中发生的任何异常,并将该异常重新抛出到任务使用任务的任何内容。例如,如果您有以下MVC代码

Async Function Index() As Task(Of ActionResult)
    Dim n as Integer = Await Method1()
    Return View()
End Function

Async Function Method1() As Task(Of Integer)
   Dim a As Integer = 0
   Dim b As Integer = 1 / b
   Return b
End Function

执行Method1内部代码的任务将捕获异常,并将其抛入Index,因为它使用的是Method1的结果,然后执行索引的任务将捕获该异常并将其重新抛出到MVC框架代码中正在使用Index的结果,然后MVC框架处理异常并显示错误页面。

当启用“仅我的代码”并且方法同步执行时,如果异常从用户代码传播出来并且消息“用户未处理”,调试器将停止。在上面的情况下,如果异常从Index传播到不是您的代码的MVC框架,则调试器将在启用JMC时停止。因为在异步方法的情况下,异常不是未处理但被Task捕获,所以它不会超出用户代码,因此禁用Just My代码不会产生任何影响。

反过来说,如果你的同步方法发生异常并且你禁用了Just My Code,调试器也不会停止,因为当禁用JMC和MVC框架时没有“User Unhandled”的概念最终会处理这个例外。