我在我的代码中观察到一些奇怪的行为,我正在尝试追踪源代码。我有两个单线程.net应用程序在同一台机器上运行并相互发送WCF消息。它们非常简单,有一个阻塞写入,然后是一个阻塞读取。我注意到在我的日志中阻塞调用,99.99%的时间我在~10毫秒内读/写。但是在非常罕见的情况下,可能需要500-2000毫秒。我试图弄清楚为什么会这样。我有一些奇怪的怪癖到我的应用程序,我正在追查,可能是罪魁祸首,但我想知道这是否进入了领域,有一些关于我不理解的框架。
所以我的问题是,当有类似阻塞调用的东西时,.net应用程序是否会在执行主线程被阻止时开始运行后台进程(例如垃圾回收)?
感谢您的时间。
答案 0 :(得分:4)
您需要考虑到系统上正在运行许多其他应用程序这一事实。通常事情可能会顺利进行,但每隔一段时间你就会有几个应用程序争夺处理器时间,这会导致你看到延迟。你看到的奇怪的延迟.01%的时间可能与.NET没什么关系,更多的是在那个特定时间点操作系统中发生的事情。
我认为问题不在于垃圾收集。您的应用程序听起来相当简单和紧凑,无论收集的垃圾可能是最小的。您正在运行开发机器,如果您像大多数开发人员一样,您将同时打开各种服务器,IDE,文本编辑器和数十个Web浏览器选项卡。试试这个:打开较重的应用程序,直到您的物理内存利用率超过75%或更高。 (即使在应用程序之间执行Alt + Tab也会显得很慢。)我猜你会看到更大的延迟和更频繁,因为会有更多的页面错误,因此更多的硬盘驱动器(主要瓶颈)减速整个过程。
答案 1 :(得分:3)
垃圾收集器有自己的专用资源,因此无论您是否使用阻止呼叫都无关紧要。
阻止呼叫基本上意味着在 UI线程上运行长时间运行的任务 。根据应用程序的类型(WPF,Windows,控制台),UI线程的定义有所不同,但是当您在UI线程上运行任务时,UI线程的所有消息都会排队等待。
您看到的效果可能是由于某些其他问题导致的,例如磁盘或网络瓶颈导致长时间运行的任务延迟。使用perfmon并将延迟时间与perfmon日志相匹配可能很有用。
答案 2 :(得分:2)
所以我的问题就是这个,当有的时候 像阻塞电话这样的事情 .net应用程序开始运行 后台进程(如垃圾 集合)而主线程 执行被阻止?
CLR在阻止呼叫期间所做的事情是完全不确定的,而不是你可以依赖的东西。您观察到的差异可能是由于您无法控制的许多因素,例如网络延迟。
答案 3 :(得分:0)
首先,如果您不使用svctraceutil,请确保使用它,因为它会为您提供大量信息。 WCF的作用取决于您使用服务/客户端设置的数百个配置选项。假设您在长期异常调用期间使用基于tcp构建的绑定,则重新建立会话或重新发送失败的数据包。使用框架的好处是,只要符合您的需求,您就不必担心具体细节。如果您需要精细控制,则可以始终实现自定义绑定或使用原始TCP / IP通信。