附加调试器的C#代码非常慢; MemoryMappedFile的错?

Kie*_*one 9 c# debugging performance .net-4.0 memory-mapped-files

我有一个客户端/服务器应用程序.服务器组件运行,以"远程处理"方式使用WCF(二进制格式化程序,会话对象).

如果我启动服务器组件并启动客户端,则服务器执行的第一项任务将在<0.5秒内完成.

如果我在连接了VS调试器的情况下启动服务器组件,然后启动客户端,则任务需要20秒才能完成.

没有代码更改 - 没有条件编译更改.无论我是否已经编译并运行32位,64位服务器组件,VS主机进程,没有VS主机进程,或者这些东西的任何组合,都会出现同样的情况.

可能很重要:如果我使用VS.NET 探查器(采样模式),那么应用程序运行速度就像没有连接调试器一样.所以我不能那样诊断它.刚检查,仪表模式也快速运行.对于并发性分析模式,同样快速.

关键数据:

  • 该应用程序使用相当繁重的多线程(标准线程池中的40个线程).无论如何,创建线程都会很快发生,而且不是一个慢点.有许多锁,WaitHandles和Monitor模式
  • 该应用程序完全没有例外.
  • 该应用程序不会创建控制台输出
  • 该应用程序完全是托管代码.
  • 该应用程序确实将磁盘上的几个文件映射到MemoryMappedFile:1x750MB和12x8MB以及一些较小的文件

测量性能:

  • 两种情况下CPU使用率都很低; 连接调试器时,CPU位于<1%
  • 两种情况下内存使用都很少; 两种情况下可能都是50或60MB
  • 发生了大量的页面错误(参考MMF),但是在附加调试器时它们发生得更慢
  • 如果VS宿主进程不使用,或基本上是"远程调试监视器"进场,则是使用一个体面的CPU,并创建一个良好的数量页面错误的.但这不是问题发生的唯一时间
  • 无论客户端如何运行,都会看到性能差异.唯一要更改的变量是通过"从调试开始"vs从Explorer启动的服务器组件.

我的想法:

  • 调试时WCF速度慢?
  • MemoryMappedFiles在调试时会变慢吗?
  • 使用了40个线程 - 调试速度慢?也许Monitors/locks通知调试器?线程调度变得奇怪/上下文切换非常罕见?
  • 宇宙背景辐射赋予VS智慧和残酷的幽默感

所有人似乎都不太可能.

所以,我的问题:

  1. 为什么会这样?
  2. 如果#1未知,我该如何诊断/发现?

Sim*_*ier 9

例外可能会显着影响应用程序的性能.有两种类型的异常:第一次机会异常(使用try/catch块正常处理的异常)和未处理的异常(最终会使应用程序崩溃).

默认情况下,调试器不显示第一次机会异常,它只显示未处理的异常.默认情况下,它还仅显示代码中发生的异常.但是,即使它没有显示它们,它仍然会处理它们,因此它的性能可能会受到影响(特别是在负载测试或大循环运行中).

要在Visual Studio中启用第一次机会异常显示,请单击"调试|异常"以调用"异常"对话框,并在"公共语言运行时"部分中选中"抛出"(您可以更具体地选择您想要的第一次机会异常)查看).

要启用源自应用程序中任何位置的第一次机会异常显示,而不仅仅是代码,请单击"工具|选项|调试|常规"并禁用"启用我的代码"选项.

对于这些特定的"取证模式"情况,我还强烈建议启用.NET Framework源步进(它需要禁用"启用我的代码").了解正在发生的事情是非常有用的,有时只是看着调用堆栈是非常鼓舞人心的 - 特别是在宇宙辐射混合的情况下有用:-)

两篇相关的有趣文章:


Tyr*_*ron 5

由于这是谷歌搜索此问题时的第一个结果,因此我想在此处添加我的问题解决方案,以期像我的案例一样为某人节省2个小时的研究时间。

没有调试器的情况下,我的代码从30秒开始变慢,而使用调试器时,我的代码从4分钟开始变慢。因为我忘了删除条件断点。这些似乎极大地减慢了执行速度,因此请当心那些