【问题标题】:How to use Environment.StackTrace in a conditional expression for a breakpoint in VS2015如何在 VS2015 断点的条件表达式中使用 Environment.StackTrace
【发布时间】:2016-11-09 19:37:17
【问题描述】:

我正在尝试调试一个问题,如果我可以在属性的 getter 中设置一个断点,这将非常有帮助,但我不需要每次从 CanExecute 调用中的某个按钮调用它时都中断我的用户界面。我的想法是我可以简单地在不包含该字符串的调用堆栈上设置断点,但这似乎不起作用。我能想到的最好的解释方法是使用设置的图像和被击中的断点的输出。

正如您在图像中看到的,断点的条件设置在被命中时直接输出,在输出中您可以看到它被命中了几次.get(): true - 正确。但是,当它拍摄此屏幕截图时,它被击中,条件为假,如输出所示。当断点被错误地击中时,程序停止了。

我做错了什么 - 这可能吗?在我看来就像 VS2015 中的一个错误,输出可以正确评估布尔值,为什么断点条件不能这样做?

编辑,对图像进行注释,以防它在某个时候丢失。 我在一个简单地返回基础字段的属性的 get 方法中有一个断点。断点设置表明断点上有一个条件来定义它,这样它应该只在表达式!Environment.StackTrace.Contains("CanExecute") 返回真时被命中,即只有在堆栈跟踪不包含“CanExecute”字符串时才中断。 断点设置的 Action 部分使用$FUNCTION: {!Environment.StackTrace.Contains("CanExecute")} 简单地输出函数名称和条件表达式。该操作设置为不继续执行。

【问题讨论】:

    标签: c# debugging visual-studio-2015 conditional-breakpoint


    【解决方案1】:

    我不知道为什么堆栈跟踪信息在断点条件下不可用,但有一个疯狂的解决方法/黑客可以作为another answer 中概述的技术的扩展来做

    如果你使用自动属性,它不会像 “干净”一样工作,因为它需要两个断点,而自动属性只有一个点来绑定断点,但我想这是无论如何,它对汽车属性没有那么有用。


    将第一个断点放在get 方法的左大括号上(将光标设置在大括号上并按 F9)。在这个断点上设置一个动作;将"Log a message to Output Window:" 设置为

    {System.AppDomain.CurrentDomain.SetData("break", !Environment.StackTrace.Contains("CanExecute"))}
    

    并确保选中Continue execution

    return 语句上放置第二个断点(将光标设置在大括号上并按F9)。在这个断点上设置条件:

    (bool)System.AppDomain.CurrentDomain.GetData("break")
    

    根据您的格式,这可能需要“断点”窗口Debug > Windows > Breakpoints (Ctrl+Alt+B) 的帮助,以防花括号和return 语句在同一行。您可以通过右键单击“断点”窗口中的断点并选择Settings

    来编辑操作/条件

    需要转换为bool,因为GetData() 返回一个object,并且条件断点不会为您执行转换。


    它并不漂亮,由于全局状态,它在多线程环境中不能很好地工作,但在紧要关头它可能很有用。如果您需要以这种方式设置多个“条件断点”,请确保在SetData()/GetData() 中使用不同的键。

    但是,如果可以的话,通常(取决于您的编译时间和对代码与调试符号的访问)只是临时编辑代码以设置您想要中断的条件会更快/更容易。

    例如

    public Foo Selected
    {
        get
        {
            if (!Environment.StackTrace.Contains("CanExecute"))
                System.Diagnostics.Debugger.Break();
    
            return _selected;
        }
    }
    

    *在auto属性的情况下,可以在属性访问前使用CanExecute()方法中的一对动作断点将“break”设置为true,然后将“break”设置为false,对于条件使用

    (bool?)System.AppDomain.CurrentDomain.GetData("break") != false
    

    确保它在CanExecute() 之前和之后仍然会中断,但不会在期间中断。

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多