2011-04-14 66 views
2

我在观察我的代码中的一些奇怪行为,并试图追踪源代码。我有两个单线程的.net应用程序在同一台机器上运行并向对方发送WCF消息。它们非常简单,有阻塞写入,然后是阻塞读取。我已经注意到,在我的日志中的阻塞呼叫中,99.99%的时间在〜10 ms内读取/写入。但在极少数情况下,可能需要500-2000毫秒。我想明白为什么会这样。我有几个奇怪的怪癖我的应用程序,我跟踪下来,可能是罪魁祸首,但我想知道,这是进入领地里有一些关于我不明白的框架。.net框架在阻塞呼叫期间做了什么?

所以我的问题是这样的,当有一个像一个阻塞调用,并在.NET应用程序开始运行后台进程(如垃圾回收),而执行的主线程被阻塞?

谢谢你的时间。因此,如果您使用的是阻塞调用与否并不重要

+0

垃圾收集可能是罪魁祸首。任何数量的事情都可能导致延误。例如,操作系统可能会将一个或两个线程交换出内存来执行其他操作。或者更高优先级的线程阻止一个或两个线程运行。很难说。你能发布一些代码,以便我们更好地了解你遇到问题的位置吗? – 2011-04-14 21:35:05

回答

3

垃圾收集器都有自己的专用资源。

阻塞调用基本上意味着运行UI线程在长时间运行的任务。根据应用程序的类型(WPF,Windows,Console),UI线程的定义不同,但在UI线程上运行任务时,UI线程的所有消息都会排队。

你看到可能的影响因例如磁盘网络瓶颈造成的长时间运行的任务延迟其他一些问题。使用perfmon并将您的延迟时间与perfmon日志相匹配可能很有用。

+0

感谢您的测试建议。我会尝试一下,看看我可以消耗多少。我意识到性能是一个复杂的问题,所以我试图排除.net性能下降,我可能不知道。谢谢你解决GC和perfmon的想法。 – Dio 2011-04-14 21:45:43

+0

这看起来像是一个古怪的例子,例如睡眠后或类似的硬盘驱动器主轴醒来。 – Aliostad 2011-04-14 21:46:44

2

所以我的问题是这样的,当有 像一个阻塞调用,做了 .NET应用程序开始运行一个 后台进程(如垃圾 收集),而 执行的主线程被阻塞?

CLR在阻塞调用期间所做的是完全非确定性的,而不是您可以依赖的东西。您观察到的差异可能是由于许多因素无法控制,例如网络延迟。

4

你需要考虑到一个事实,即有许多您的系统上运行的其它应用。通常事情可能会平稳运行,但每隔几次,您可能会有几个应用程序争夺处理器时间,这会导致您看到延迟。您看到.01%的时间的奇怪的延迟可能与.NET毫无关系,并且与操作系统在特定时间点发生的更多有关。

我不认为这个问题是与垃圾收集。你的应用听起来相当简单和紧密,无论收集什么垃圾可能都很小。你正在运行一台开发机器,如果你像大多数开发人员一样,你将拥有各种各样的服务器,IDE,文本编辑器和几十个web浏览器选项卡。试试这个:打开较重的应用程序,直到您的物理内存使用率超过75%或更高。 (即使这样做的Alt + Tab应用程序会显得之间/是缓慢的。)我猜你会看到更大的延迟,更多的时候,因为会有更多的页面错误,因此有更多的点击到硬盘驱动器(主要瓶颈)放缓贯穿整个过程。

+0

好主意,谢谢,我会给它一个镜头。我意识到这是一个复杂的问题,有很多的罪魁祸首,我只是想排除我不知道的可能的.net。感谢测试的想法。 – Dio 2011-04-14 21:44:27

0

首先,如果您不使用svctraceutil请务必使用它,因为它会给你一个信息负载。 WCF的功能取决于您使用服务/客户端设置的数百个配置选项。假设您在长时间的异常值调用期间使用一些基于tcp的绑定,它将重新建立会话或重新传输失败的数据包。使用框架的好处和坏处是,只要满足您的需求,您无需担心具体情况。如果您需要细粒度控制,您可以始终实施自定义绑定或使用原始TCP/IP通信。