为什么我的windows服务正在启动csc.exe实例

本文关键字:启动 csc exe 实例 我的 windows 服务 为什么 | 更新日期: 2023-09-27 17:58:47

我用C#编写了一个多线程windows服务。由于某种原因,每次派生线程时都会启动csc.exe。我怀疑这与线程本身有关,但事实上,它是在每个线程的基础上发生的,而且这些线程是短暂的,这使得问题非常明显:许多csc.exe进程不断启动和停止。

性能仍然很好,但我希望如果我能消除这种情况,它会有所改善。然而,更让我担心的是,McAfee正试图扫描csc.exe实例,并最终杀死了该服务,显然是在扫描过程中其中一个实例退出时。我需要在商业上部署此服务,因此更改McAfee设置不是一个解决方案。

我假设我的代码中有什么东西触发了动态编译,但我不确定是什么。还有人遇到这个问题吗?有什么解决办法吗?

更新1:

根据@sixlettervariables的建议和链接进行进一步研究后,问题似乎源于XML序列化的实现,如微软关于XmlSerializer:的文档所示

为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。

微软在同一文档中指出了进一步的优化:

基础结构查找并重用这些程序集。此行为仅在使用以下构造函数时发生:

XmlSerializer。XmlSerializer(类型)

XmlSerializer。XmlSerializer(类型,字符串)

这似乎表明,只要使用了两个指定构造函数中的一个,代码生成和编译在第一次使用时只会发生一次。然而,我并没有从这个优化中受益,因为我正在使用另一种形式的构造函数,特别是:

公共XmlSerializer(类型类型,类型[]extraTypes)

进一步阅读,发现这也恰好是我在执行代码时观察到的内存泄漏的一个可能解释。同样,来自同一个文档:

如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且从未卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数中的一个。否则,必须将程序集缓存在哈希表中。

微软上面建议的两种解决方案是我的最后手段。使用另一种形式的构造函数是不可取的(我使用"extrates"形式对派生类进行序列化,这是微软文档支持的用法),我不确定我是否喜欢管理跨多个线程使用的程序集缓存的想法。

因此,我有sgen’d,并看到了按预期生成的类型的序列化程序的结果程序集,但当我的代码执行时,没有加载sgen生成的程序集(根据融合日志查看器和进程监视器中的观察结果)。我目前正在探究为什么会出现这种情况。

更新2:

当我使用两个";"更友好";XmlSerializer构造函数(请参阅上面的Update 1)。例如,当我使用XmlSerializer(Type)时,sgen’d程序集加载,并且不执行运行时代码生成/编译。但是,当我使用XmlSerializer(Type, Type[])时,程序集不会加载。对此找不到任何合理的解释。

因此,我将恢复使用一个受支持的构造函数和sgen'ing。这种组合消除了我最初的问题(csc.exe的启动),以及另一个相关问题(上面更新1中提到的XmlSerializer引发的内存泄漏)。然而,这确实意味着,我必须恢复到派生类型的不太理想的序列化形式(在基类型上使用XmlInclude),直到框架中发生一些变化来解决这种情况。

为什么我的windows服务正在启动csc.exe实例

心理调试:

  • 您的Windows服务执行XML序列化/反序列化

    为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。

如果是这种情况,您可以先验地构建这些XML序列化程序集。