【问题标题】:Debugger break location with F# exception handling带有 F# 异常处理的调试器中断位置
【发布时间】:2014-02-17 21:50:31
【问题描述】:

我最近遇到了这个问题,想检查一下我是否对 F# 异常有误解。我正在使用 Visual Studio 2012。鉴于以下 F# 代码:

[<EntryPoint>]
let main argv = 
    try
        raise (System.AccessViolationException("foo"))
        printfn "Should not get here"
        raise (System.AccessViolationException("foo"))
        printfn "Should not get here either"
    with | :? System.FormatException -> printfn "Should not get here"

这将引发 with 语句不应捕获的 AccessViolationException,因为 with 仅处理 System.FormatException。我希望调试器在异常发生时位于第一个raise,但实际上它位于with 的末尾:

现在的问题是我看不到异常是从哪里引发的,我也看不到有关异常的任何信息,例如堆栈跟踪。我不认为我想更改个别异常的异常设置,因为我想知道任何未处理的异常(类似于C#VB.NET)的位置,而不是在抛出时。

如果只是这样,那没关系,但我只是想问一下,因为我对F# 不是很熟悉,我想确保我没有遗漏任何东西。我在网上查了一下,没有找到任何相关信息。

【问题讨论】:

    标签: f#


    【解决方案1】:

    除非您想修改异常设置以在抛出该异常类型(或异常设置中的一类异常)时中断,否则您需要确保您的代码能够处理未处理的异常,但最适合您的代码。

    try
        raise (System.AccessViolationException("foo"))        
    with 
        | :? System.FormatException -> printfn "Should not get here"
        | _ as ex ->             
    #if DEBUG
            System.Diagnostics.Debugger.Break();
    #else
            printfn "Unhandled exception ('%s'): '%s'" (ex.GetType().Name) ex.Message
    #endif
    

    【讨论】:

    • 感谢您的帖子。是的,我同意您通常想要处理通用异常,但在某些情况下(例如在调试时)允许异常传播以使调试器在抛出位置中断是有用的。然后可以查看局部变量的值等。我更想知道这是设计使然,还是我遗漏了一些东西,因为它与 C# 和 VB 的工作方式不同。
    • 不幸的是,如果没有在异常设置中为该异常显式启用 Break On Throw,我认为这是不可能的。 Exception Assistant 的文档指定它可用于 VB.Net 和 C#,所以我认为这只是一个幸运的巧合,它也恰好与 F# 一起工作并且不应该被假定支持等效功能。跨度>
    • 好的。我不想因异常而中断,而是因未处理的异常而中断。我认为这正是它在 F# 中的工作方式,我对此很好,只是确保我没有遗漏任何东西。
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 2012-11-08
    • 2014-07-23
    • 1970-01-01
    相关资源
    最近更新 更多