Visual Studio - 调试模式 vs 发布模式

15

我建立了一个针对.NET 2.0的Windows服务,在VS 2008中运行它作为控制台应用程序来调试。

控制台应用程序工作得很好。我把它放在我的本地计算机上作为服务,以调试模式编译,仍然非常好。现在我准备发布它,但突然间,当我将其设置为发布模式时,服务编译和安装了,但是没有任何事情发生。(没有任何代码在服务中运行)。

我意识到发布模式和调试模式是属性配置设置,但似乎在发布模式下,即使我检查定义DEBUG常量、取消优化代码和设置调试信息为'full',它仍然做不了任何事情。

将它设置回调试模式,它就像魔法一样再次工作了。

(顺便说一下,我尝试将目标框架重置为3.5,以确保那不是问题。)

所以我的问题(按重要性排序)如下:

  1. 使用我的“调试”版本会有任何问题吗?

  2. 除了我已经尝试过的三个设置之外,调试和发布之间有哪些不同的设置?

  3. 这对我来说似乎是一个奇怪的错误,引起了我的好奇心。有什么想法可以解决这个问题吗?

编辑: 应该提一下,我已经使用自定义安装程序了。基本上我编译程序(无论是调试还是发布),然后用相应的安装程序安装它。


你确定在发布模式下安装了服务(而且安装正确)吗? - Josh E
你需要一个安装程序和自定义操作来安装Windows服务。更多信息,请参见:http://msdn.microsoft.com/zh-cn/library/d56de412(VS.80).aspx - Robert Harvey
服务是否进入了运行状态?事件日志中有什么记录吗? - Stephen Cleary
@Robert Harvey:我有一个安装程序。我的做法是在“调试”模式下构建项目,然后使用创建的安装程序将服务安装到我的本地机器上。然后我使用services.msc来停止、启动和重新启动。@Josh E:考虑到我每次安装都是以相同的方式进行的,无论我如何编译它,我不知道我会错在哪里?@Stephen Cleary:我可以进入事件查看器,但不确定我要找什么? - Brandi
1
使用 System.ServiceProcess.ServiceBase.EventLog 实例在服务启动时向事件查看器写入消息。例如,在 OnStart() 回调中,编写一条消息,指示您至少已经完成了这一步。这将帮助您缩小问题发生的范围。很有可能,您的服务会触发一个异常,导致其关闭。如果是这样,在服务的 Main() 函数中放置一个 try-catch 块,并在 catch 块中编写一条消息到事件查看器中,其中包括堆栈跟踪,将显示问题发生的确切位置。 - Matt Davis
2个回答

18

1) 如果应用程序变得更慢并且使用更多内存,间接地可能会影响它。

2) 当它在调试模式下运行时,有些事情会以不同的方式工作,例如:

  • 代码编译时添加了一些额外的NOP指令,使每个代码行开头至少有一条指令,因此可以在任何一行放置断点。

  • 指令可以在发布模式下重新排列,但不能在调试模式下重新排列,因此可以逐步执行代码,并且结果将对应于源代码的确切顺序。

  • 垃圾回收器通过让引用在其整个范围内生存而不仅仅是在使用期间来不同地工作,因此在调试模式下查看变量时,可以防止变量在作用域结束之前消失。

  • 异常包含更多信息,并且在抛出时需要更长时间进行处理。

所有这些差异都相对较小,但它们是实际的差异,在某些情况下可能很重要。

如果在调试模式和发布模式之间看到性能巨大差异,则通常是代码存在问题,例如,如果它抛出并捕获了大量异常。如果代码中存在竞争条件,则可能仅在发布模式下发生,因为调试模式中存在某些额外的开销会使代码运行略慢。

3) 至于您的服务问题是什么,我不知道,但似乎与如何在调试模式或发布模式下执行代码无关。代码将在任何情况下启动,如果代码存在问题,它将崩溃,并且您可以在事件日志中看到它。


谢谢,看起来它运行得非常完美,我刚刚就这样部署了它。我仍然很困惑发生了什么,但是没错,这不是代码的问题。再次感谢。 :) - Brandi

0

我不确定我能谈论 #1 或者 #2,但是当我遇到类似的问题时,这通常是由于线程/并发错误引起的。我不知道你的应用程序有多大,但这可能是一个好的起点。


Chad,虽然OP提出的问题可能是有效的,但我认为这不太可能是问题的原因;更有可能是配置/安装问题。 - Josh E
它很小,基本上只有一个计时器,在更新时调用一个函数。我很确定线程安全并不是它的问题,因为当释放模式无法工作时,甚至不会运行构造函数,而使用调试设置编译时完美地工作。总体来说,这是非常好的建议,谢谢。 :) - Brandi

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