我有一个客户端/服务器应用程序。服务器组件运行,以“远程”方式使用 WCF(二进制格式化程序、 session 对象)。
如果我启动服务器组件并启动客户端,服务器执行的第一个任务将在 <0.5 秒内完成。
如果我启动附加了 VS 调试器的服务器组件,然后启动客户端,任务需要超过 20 秒才能完成。
没有代码更改 - 没有条件编译更改。无论我在 32 位、64 位、使用 VS 托管进程、不使用 VS 托管进程或这些东西的任何组合中编译和运行服务器组件,都会发生同样的情况。
可能很重要:如果我使用 VS.NET profiler(采样模式),那么应用程序的运行速度就像没有附加调试器一样快。所以我不能那样诊断。刚刚检查过,检测模式也运行得很快。与并发分析模式相同,工作速度很快。
关键数据:
- 该应用使用相当繁重的多线程(标准线程池中有 40 个线程)。无论如何创建线程都会很快发生并且不是一个慢点。有很多锁、
WaitHandle
和Monitor
模式 - 该应用不会引发任何异常。
- 该应用不创建控制台输出。
- 该应用完全是托管代码。
- 该应用确实将磁盘上的一些文件映射到 MemoryMappedFile:1x750MB 和 12x8MB 以及一些较小的文件
测量性能:
- 两种情况下的 CPU 使用率都极低;附加调试器时,CPU 占用 <1%
- 在这两种情况下,内存使用都很少;两种情况都可能是 50 或 60MB
- 有很多页面错误发生(引用 MMF),但是当附加调试器时它们发生得更慢
- 如果未使用 VS 托管进程,或者基本上“远程调试监视器”发挥作用,那么会使用大量 CPU 并产生大量页面错误。但这不是问题发生的唯一时间
- 无论客户端如何运行,都会看到性能差异。唯一发生变化的变量是服务器组件是通过“开始调试”运行还是从资源管理器启动。
我的想法:
- WCF 在调试时速度很慢?
- MemoryMappedFiles 在调试时很慢?
- 使用了 40 个线程 - 调试速度慢?也许监视器/锁通知调试器?线程调度变得奇怪/上下文切换很不频繁?
- 宇宙背景辐射赋予VS智慧和残忍的幽默感
一切似乎都不太可能。
所以,我的问题:
- 为什么会这样?
- 如果 #1 未知,我该如何诊断/找出?
最佳答案
因为这是谷歌搜索这个问题时的第一个结果之一,我想在这里添加我的问题解决方案,希望像我的情况一样为某人节省 2 小时的研究时间。
我的代码从没有连接调试器的 30 秒减慢到连接调试器的 4 分钟。因为我忘了删除条件断点。这些似乎会极大地减慢执行速度,所以要小心那些
关于附有调试器的 C# 代码非常慢; MemoryMappedFile 的错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7828041/