3

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

断点设置

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

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

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

4

1 回答 1

1

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

如果您使用自动属性,它不会像“干净”一样工作,因为它需要两个断点,并且自动属性只有一个点可以将断点绑定到,但我想这对自动属性没有那么有用。


将第一个断点放在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

强制转换为返回 anbool是必需的,并且条件断点不会为您执行强制转换。GetData()object


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

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

例如

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

        return _selected;
    }
}

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

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

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

于 2018-12-11T03:26:29.347 回答