我已经开始使用内部开发人员工具几周了,但是我遇到了一个丑陋的绊脚石我无法找到一个好的解决方案。我希望有人可以提供一些关于在.NET中使用现有框架的最佳方法的想法或指导。
背景知识:此工具的目的是将多种不同类型的日志文件(Windows事件日志,IIS,SQL跟踪等)加载到同一数据库表中,以便对它们进行排序和检查。我个人的目标是简化整个过程,以便我们只进行一次传递,不要将整个日志缓存在内存或磁盘中。当日志文件达到数百MB或GB范围时,这很重要。快速的性能是好的,但缓慢且不引人注目(允许您在此期间处理其他事情)比运行速度更快但在此过程中垄断系统更好,因此我专注于最小化RAM和磁盘使用。
到目前为止,我已经尝试了几种不同的设计,试图将其归结为简单的东西。我希望日志解析器的核心 - 必须与任何外部库或文件交互以实际读取数据的部分 - 尽可能简单并符合标准接口,以便添加对新格式的支持尽可能简单。目前,parse方法返回IEnumerable<Item>
,其中Item
是自定义结构,我使用yield return
来最小化缓冲量。
然而,我们很快遇到了一些丑陋的限制:图书馆(通常由Microsoft提供)来处理这些文件格式。最大和最丑陋的问题:其中一个库仅适用于64位。另一个(用于SSMS日志的Microsoft.SqlServer.Management.Trace TraceFile)仅适用于32位。众所周知,您无法混合和匹配32位和64位代码。由于本练习的整个要点是有一个可以处理任何格式的实用程序,我们需要一个单独的子进程(在这种情况下是处理32位的部分)。
最终结果是我需要64位主进程来启动32位子进程,为其提供解析日志文件所需的信息,并以某种方式将数据流回来。需要将整个内容缓冲到内存或磁盘。起初我尝试使用stdout,但是由于任何大量的数据而崩溃了。我尝试过使用WCF,但它并不是专门用来处理&#34;服务&#34;作为&#34;客户&#34;的孩子,很难让他们从他们想要的工作方式向后同步,而且我不知道我是否实际上可以让他们正确地传输数据。我不想使用打开不安全网络端口的机制,或者如果有人运行多个实例,可能会意外串扰(我希望这种情况能够正常工作 - 每个64位主进程都会产生并运行它自己的孩子)。理想情况下,我希望在32位子代中运行的解析器的核心看起来与在64位父级中运行的解析器的核心相同,但我不知道它是否甚至可能继续使用yield return
,即使有一些包装器来帮助管理IPC。 .NET中是否有任何现有的框架使这相对容易?
答案 0 :(得分:1)
WCF确实有P2P模式,但如果您的所有进程都是本地计算机,那么最好使用IPC,例如命名管道,因为后者在内核模式中运行没有前者的消息传递开销。
如果不能尝试COM,那么在32位和64位进程之间不应该有问题。 - Tell me more
答案 1 :(得分:0)
如果有人遇到这种情况,我会发布我们最终确定的解决方案。关键是要将进程间WCF服务接口重新定义为与进程内IEnumerable
接口不同。我们没有尝试跨越进程边界yield return
,而是使用了一个使用枚举器的代理层,因此我们可以一遍又一遍地调用“给我一个项目”方法。它可能比真正的流式解决方案具有更多的性能开销,因为每个项目都有一个方法调用,但它似乎确实完成了工作,并且它不会泄漏或消耗内存。
我们确实遵循了Micky关于使用命名管道的建议,但仍然在WCF中。我们还使用命名信号量来协调这两个进程,因此在“子服务”完成启动之前我们不会尝试进行服务调用。