如何从代码中检测Visual Studio调试执行上下文?

时间:2014-03-07 18:46:39

标签: c# visual-studio

我正在寻找一种方法来检测在Visual Studio中的调试会话期间如何调用代码。试图区分这两种情况:

  • 普通调试,无论是跑步还是单步。
  • 通过调试器本身调用,例如从监视窗口调用我的ToString。

(我这样做是因为我想要在第二种情况下禁用一些非发布线程验证代码。)

任何人都有办法做到这一点,或者有关于要追求的事情的想法?我对hacky,tricksy方法很好,即使它们特定于特定版本的VS.

不能工作的事情:

  • 抓住StackTrace并寻找一些神奇的东西,这意味着调试器正在调用,而不是常规代码。 VS使用当前状态的当前线程来调用Watch窗口,所以所有StackTrace将会看到调试器断点处的当前堆栈+ Watch窗口正在调用的getter / ToString,就在它的顶部。

2 个答案:

答案 0 :(得分:2)

当Visual Studio假定的方法是纯粹的(即评估对程序状态没有影响)时,通常会出现这种情况,或者有副作用或者有调试器违反的前提条件。

使用以下工具可以最好地解决这些问题:

  • DebuggerBrowsableAttribute:将此属性应用于属性:

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    
    • 应用于get方法不纯的所有属性,即getter通过设置缓存值或其他方式改变程序的状态
    • 应用于get方法具有调试器可能违反的前提条件的所有属性,例如线程限制,跨线程调用(如果使用COM互操作,请不要忘记隐式)
  • DebuggerDisplayAttribute:将此属性应用于ToString()实现执行非平凡操作的所有类型(避免调试器性能影响)或具有调试器可能不满足的前提条件(例如线程要求)。对于这些类型,此属性使用代替调用ToString()

  • DebuggerTypeProxyAttribute:将此属性应用于需要特别考虑调试器中信息的显示时间,内容和方式的类型。 .NET框架本身广泛使用此属性来提供List<T>HashMap<T>类型的清晰输出等功能,甚至可以改进Lazy<T>类型的可用信息,这些类型有时可以评估和其他时间可能会影响该计划的状态。

答案 1 :(得分:1)

就普通调试而言,我认为这就是你想要的:

System.Diagnostics.Debugger.IsAttached

这是documentation

但这对观察窗无效。 关于这一点,也许StackTrace课可以提供帮助,但我自己没有尝试过。它位于相同的名称空间中。