为什么我的windows服务启动CSC.EXE的实例? [英] Why is my windows service launching instances of csc.exe?

查看:129
本文介绍了为什么我的windows服务启动CSC.EXE的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用C#编写多线程Windows服务。出于某种原因,CSC.EXE正在每个线程被产生的时间推出。我怀疑它的穿线本身有关,但它发生在每个线程的基础,而这些线程是短命的事实,使得问题非常明显:很多CSC.EXE进程不断启动和停止



性能还是蛮不错的,但我相信它会改善,如果我可以消除这一点。不过,我担心更是迈克菲正试图扫描CSC.EXE实例,并最终杀死服务,显然,当一个实例退出中旬扫描。我需要商业化部署该服务,因此更改设置迈克菲是不是一个解决方案。



我认为东西在我的代码触发动态编译,但我不知道什么。任何人都遇到这样的问题? ?解决它的任何想法。



更新1:



在进一步研究的基础从@sixlettervariables的建议和链接,这个问题似乎从XML序列化的实施,遏制,在的微软对XmlSerializer的文档:




要提高性能,XML序列化基础设施的动态生成组件序列化和反序列化指定的类型。




微软进一步上指出的优化在同一个文档:




结构发现和重用的组件。



XmlSerializer.XmlSerializer(类型)



XmlSerializer.XmlSerializer(:使用下面的构造函数时,才会出现这种情况型,字符串)




这似乎表明,代码生成和编译将仅出现一次,在第一次使用,只要其中一个两个指定构造函数使用。不过,我不从这个优化,因为我使用的构造的另一种形式中获益,具体为:




公开的XmlSerializer(类型类型,键入[] extraTypes)




进一步阅读了一下,事实证明,这也恰好是内存泄漏一个可能的解释是我的代码执行时,我一直在观察。再次,从同一个文档:




如果您使用任何其他构造函数,可生成相同的组件的多个版本,从不卸载,这导致了内存泄漏和性能不佳。最简单的解决方法是使用前面提到的两个构造函数中的一个。否则,您必须在缓存哈希表的程序集。




这两个解决方法,微软建议以上是对我来说是最后的手段。要构造的另一种形式是不可取的(我用了extratypes的形式派生类的序列化,这是每个微软的文档支持使用),我不知道我喜欢管理的高速缓存的想法组合件在多个线程中使用。



所以,我的 SGEN 'd和查看结果如预期所产生的类型我的序列化器装配,但是当我的代码执行SGEN生产装配在未加载(每个观察融合日志查看器和进程监视器)。 。我目前正在探索为什么是这样的情况。



更新2:



的sgen'd组件加载罚款当我用两个友好的XmlSerializer构造函数之一(参见更新1,以上)。当我使用的XmlSerializer(类型),例如,sgen'd装配载荷和没有运行时代码生成/编译执行。然而,当我使用 XmlSerializer的(类型,类型[]),装配不加载。找不到这方面的任何合理的解释。



所以我恢复到使用支持的构造函数和sgen'ing之一。这种结合消除了我原来的问题(CSC.EXE的开展),加上一个其他相关问题(在上面更新1中提到的XmlSerializer的诱导内存泄漏)。然而,这并不意味着,我必须恢复到的序列化派生类型(在基本类型中使用 XmlInclude )的一个次优的形式,直到东西在改变。框架来处理这种情况。


解决方案

心理调试:





如果这是你可以建造这些XML序列化的情况下,组件的先验。



I've written a multi-threaded windows service in C#. For some reason, csc.exe is being launched each time a thread is spawned. I doubt it's related to threading per se, but the fact that it is occurring on a per-thread basis, and that these threads are short-lived, makes the problem very visible: lots of csc.exe processes constantly starting and stopping.

Performance is still pretty good, but I expect it would improve if I could eliminate this. However, what concerns me even more is that McAfee is attempting to scan the csc.exe instances and eventually kills the service, apparently when one the instances exits in mid-scan. I need to deploy this service commercially, so changing McAfee settings is not a solution.

I assume that something in my code is triggering dynamic compilation, but I'm not sure what. Anyone else encounter this problem? Any ideas for resolving it?

Update 1:

After further research based on the suggestion and links from @sixlettervariables, the problem appears to stem from the implementation of XML serialization, as indicated in Microsoft's documentation on XmlSerializer:

To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types.

Microsoft notes an optimization further on in the same doc:

The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:

XmlSerializer.XmlSerializer(Type)

XmlSerializer.XmlSerializer(Type, String)

which appears to indicate that the codegen and compilation would occur only once, at first use, as long as one of the two specified constructors are used. However, I don't benefit from this optimization because I am using another form of the constructor, specifically:

public XmlSerializer(Type type, Type[] extraTypes)

Reading a bit further, it turns out that this also happens to be a likely explanation for a memory leak that I have been observing when my code executes. Again, from the same doc:

If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable.

The two workarounds that Microsoft suggests above are a last resort for me. Going to another form of the constructor is not preferred (I am using the "extratypes" form for serialization of derived classes, which is a supported use per Microsoft's docs), and I'm not sure I like the idea of managing a cache of assemblies for use across multiple threads.

So, I have sgen'd, and see the resulting assembly of serializers for my types produced as expected, but when my code executes the sgen-produced assembly is not loaded (per observation in the fusion log viewer and process monitor). I'm currently exploring why this is the case.

Update 2:

The sgen'd assembly loads fine when I use one of the two "friendlier" XmlSerializer constructors (see Update 1, above). When I use XmlSerializer(Type), for example, the sgen'd assembly loads and no run-time codegen/compilation is performed. However, when I use XmlSerializer(Type, Type[]), the assembly does not load. Can't find any reasonable explanation for this.

So I'm reverting to using one of the supported constructors and sgen'ing. This combination eliminates my original problem (the launching of csc.exe), plus one other related problem (the XmlSerializer-induced memory leak mentioned in Update 1 above). It does mean, however, that I have to revert to a less optimal form of of serialization for derived types (the use of XmlInclude on the base type) until something changes in the framework to address this situation.

解决方案

Psychic debugging:

If this is the case you can build these XML Serializer Assemblies a-priori.

这篇关于为什么我的windows服务启动CSC.EXE的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆