.NET 编译器 -- DEBUG 与 RELEASE

.NET Compiler -- DEBUG vs. RELEASE

提问人:Pete 提问时间:8/27/2008 更新时间:3/16/2010 访问量:11914

问:

多年来,我一直在 VB.NET 中使用 DEBUG 编译器常量将消息写入控制台。我也一直在以类似的方式使用 System.Diagnostics.Debug.Write。我的理解是,当使用 RELEASE 作为构建选项时,编译器会省略所有这些语句,从而将生产代码从调试语句的开销中解放出来。最近,在使用 Silverlight 2 Beta 2 时,我注意到 Visual Studio 实际上附加到我从公共网站运行的 RELEASE 版本,并显示了我认为甚至没有编译的 DEBUG 语句!现在,我的第一个倾向是假设我的环境有问题,但我也想问任何对 System.Diagnostics.Debug 和 DEBUG 构建选项有深入了解的人,我可能在这里误解了什么。

.NET 编译器构造 调试

评论


答:

-6赞 Vincent 8/27/2008 #1

根据我的经验,在 VB.NET 中在调试和发布之间进行选择没有区别。您可以将自定义操作添加到这两个配置中,但默认情况下我认为它们是相同的。

使用 Release 肯定不会删除 System.Diagnostics.Debug.Write 语句。

评论

0赞 Robert Taylor 10/12/2008
它们不一样;默认情况下,Release 模式实际上会删除对 Debug.Write 的调用,因为该方法应用了 ConditionalAttribute。
1赞 juan 8/27/2008 #2

我所做的是将对 Debug 的调用封装在我自己的类中并添加一个预编译器指令

public void Debug(string s)
{
#if DEBUG
    System.Diagnostics.Debug(...);
#endif
}
1赞 Chris Karcher 8/27/2008 #3

正如您所说,使用 DEBUG 编译器符号实际上会省略程序集中的代码。

我相信System.Diagnostics.Debug.Write将始终输出到附加的调试器,即使您已在发布模式下构建也是如此。根据 MSDN 文章

将有关调试的信息写入 Listeners 集合中的跟踪侦听器。

如果你不需要任何输出,你需要用 DEBUG 常量包装对 Debug.Write 的调用,就像 Juan 说的那样:

#if DEBUG
    System.Diagnostics.Debug.Write(...);
#endif
22赞 Mike 8/27/2008 #4

首选方法是实际使用 conditional 属性来包装调试调用,而不是使用编译器指令。#ifs 可能会变得棘手,并可能导致奇怪的构建问题。

使用条件属性的示例如下(在 C# 中,但也适用于 VB.NET):

[ Conditional("Debug") ]
private void WriteDebug(string debugString)
{
  // do stuff
}

在未设置 DEBUG 标志的情况下进行编译时,将删除对 WriteDebug 的任何调用,因为假定使用 Debug.Write() 时会发生调用。

评论

1赞 James 1/19/2012
我认为使用该方法仍然是实际发布程序集的一部分,它只是没有加载。所以我想删除调试代码的唯一真正方法是使用编译器指令?ConditionalAttribute
2赞 Pete 8/27/2008 #5

我也读了这篇文章,它使我相信,当未定义 DEBUG 时,在 System.Debug 函数上声明的 ConditionalAttribute 会导致编译器完全省略此代码。我认为 TRACE 也是如此。也就是说,System.Diagnostics.Debug 函数必须具有 DEBUG 和 TRACE 的 ConditionalAttributes。我的这个假设是错误的。单独的 Trace 类具有相同的函数,这些函数定义依赖于 TRACE 常量的 ConditionalAttribute。

从 System.Diagnostics.Debug: _ 公共共享子写入 ( _ 消息为字符串 _ )

从 System.Diagnostics.Trace: _ 公共共享子 WriteLine ( _ 消息为字符串 _ )

看来我最初的假设是正确的,System.Diagnostics.Debug(或系统。Diagnostics.Trace) 语句实际上不包含在编译中,就像它们包含在 #IF DEBUG(或 #IF TRACE)区域中一样。

但我也从你们那里了解到,并验证了 RELEASE 版本本身并不能解决这个问题。至少对于Silverlight项目,这些项目仍然有点不稳定,您需要进入“高级编译选项...”并确保未定义 DEBUG。

我们从 .NET 1.1/VS2003 跳到 .NET 3.5/VS2008,所以我认为其中一些曾经以不同的方式工作,但也许它在 2.0/VS2005 中发生了变化。

5赞 Bjorn Reppen 8/27/2008 #6

检查 Debug.Write 方法。它标有

[Conditional("DEBUG")]

属性。

ConditionalAttribute 的 MSDN 帮助指出:

向编译器指示方法 应忽略调用或属性 除非指定的条件 编译符号。

生成配置是否具有 release 或 debug 标签并不重要,重要的是是否在其中定义了 DEBUG 符号。

1赞 Elad A 3/16/2010 #7

要选择是要编译还是删除调试信息,

在项目的属性窗口中输入“Build”选项卡。

选择正确的配置(Active/Release/Debug/All)并确保 检查“DEBUG 常量”,如果你想要信息, 或者,如果没有,请取消选中它。

应用更改并重新生成