在.NET中,调试版本与发布版本的区别

65

继续我之前的问题,是否有一份详尽的文档列出了C#应用程序中调试模式和发布模式的所有可用区别,特别是在Web应用程序中?

有哪些差异?


相关问题:https://dev59.com/xHE95IYBdhLWcg3wSsCD - Brian Rasmussen
9个回答

55
“Debug”和“Release”只是由Visual Studio定义的预定义项目配置名称。要查看区别,请查看Visual Studio中项目属性下的构建选项卡。
VS2005中的区别包括:
- 在Debug配置中定义了DEBUG常量 - 在Release配置中启用了代码优化
以及其他你可以通过点击“高级”按钮看到的差异。
但你可以:
- 在项目属性/构建中更改Debug和Release配置的构建设置 - 通过在解决方案资源管理器中右键单击解决方案并选择“配置管理器”来创建自己的自定义配置
我认为DEBUG常量的行为相当清晰(可以在#if预处理器指令或ConditionalAttribute中引用)。但我不知道有没有关于启用了哪些优化的全面文档 - 实际上我怀疑微软可能会随时提高他们的优化器而不事先告知。

8
这个答案是正确的,但只是表面上的,我希望了解更多关于代码优化和DEBUG常量如何影响代码行为的细节。在代码行为方面会有很多差异,你可以看我的之前的问题来举例说明。 - MichaelT
以下问题怎么解决呢?在一个ASP.NET MVC项目中有三个配置:基本(web)、调试(web.debug)、发布(web.release)。假设我们通过转换将调试和发布连接字符串设置到相应的配置文件(调试和发布)中。在发布时,我们可以根据发布对话框中的选择进行发布。但是,在运行应用程序时,尽管我选择了“调试”,它却使用了“发布”配置(因为我在基本和调试配置中设置了调试配置),这正常吗? - user5871859
  1. 当在调试或发布模式下运行应用程序时,VS使用基本的web config还是相应的web config(web.debug.confg或web.release.config)?
- user5871859
@Jason,当在Visual Studio中运行项目时,web.config转换不会被使用。只有在发布时才会使用它们。因此,无论您处于调试模式还是发布模式,您都将在基本的web.config文件中获得连接字符串。 - Joe
我听说过它,但从未使用过。 - user5871859
显示剩余4条评论

18

我不知道有一个简洁的文档,但是:

  • 在发布版本中,Debug.Write调用会被剥离
  • 在发布版本中,由于优化,您的CallStack可能会看起来有点“奇怪”,如Scott Hanselman所概述的那样。

17

调试和发布只是不同解决方案配置的标签。如果需要,您可以添加其他配置。如果您希望添加更多配置,请使用“配置管理器”。

http://msdn.microsoft.com/en-us/library/kwybya3w.aspx

主要差异:

  1. 在调试DLL中,添加了额外的指令,以使您可以在Visual Studio的每个源代码行上设置断点。此外,代码不会被优化,以便您调试代码。 在发布版本中,这些额外的指令被删除。

  2. PDB文件仅在Debug模式下创建,而不是在发布模式下创建。

  3. 在发布模式下,代码通过内置于JIT编译器中的优化器进行优化。它进行以下优化:

    • 方法内联 - 方法调用被替换为注入方法的代码。

    • CPU寄存器分配 - 本地变量和方法参数可以保留在CPU寄存器中,而无需(或更少)存储回堆栈框架

    • 数组索引检查消除 - 在使用数组时的一个重要优化(所有.NET集合类都在内部使用数组)。当JIT编译器可以验证循环从不索引数组超出边界时,它将消除索引检查。

    • 循环展开 - 短循环(最多4个)具有小体的代码被消除,重复循环体中的代码。

    • 无用代码消除 - 类似if(false) { /.../ }的语句会被完全消除。

    • 代码提升-循环内部不受循环影响的代码可以移出循环。

    • 公共子表达式消除。x = y + 4; z = y + 4;变为z = x


我的代码在调试模式下运行良好,但在发布模式下会出现错误。我不知道发生了什么。 - rlinner

17

没有一份文件列出了所有的差异。除了已经列出的一些差异之外,在Debug模式下编译会关闭大部分在运行时执行的JIT编译器优化,并且向符号数据库文件(.pdb)发射更完整的调试信息。

另一个重要的区别是,GC行为有所不同,即JIT编译器将插入适当/需要的GC.KeepAlive()调用,以支持调试会话。


7

如果你使用任何ASP.NET Ajax控件,其中一个主要的性能问题是:在发布时从JavaScript库中删除调试信息,我已经看到复杂页面的主要性能提升。基于这个设置,其他基于Web的资源可能会被缓存或不被缓存。

此外,请记住,Web应用程序中的Debug / Release由web.config文件决定,而不是您在Visual Studio中的设置。

<system.web>
    <compilation debug="true">

更多信息:


6

您也可以使用预处理器标记管理您想要在调试或发布时运行的某些代码部分:

 #if DEBUG
    // Some code running only in debug
 #endif

或者
 #if NOT DEBUG
    // Some code running only in release
 #endif

5
在调试模式下,使用GDI+进行绘图速度较慢。

3

不是完全无法调试,而是会出现问题。 - nawfal

1
当我将可执行文件分发到另一台机器时,出现了一个错误提示,指示系统缺少MSVCP110D.dll。
这个问题的解决方案在Stack Overflow的问题中有说明:Visual Studio MSVCP110D.dll is missing
在XXXXD.dll中,D表示DLL文件是DLL文件的调试版本。但是,MS Visual C++ Redistributable包仅包含DLL文件的发布版本。
这意味着,如果你需要分发由Visual C++开发的程序,你需要在Release模式下构建它。同时,在目标机器上安装MS Visual C++ Redistributable(正确的版本)也是必须的。
因此,我认为这是调试模式和发布模式之间的关键区别之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接