C# 4.0 c#windows服务中vb6 COM dll使用的可用内存
我对使用解决方案中引用的VB6 COM dll的windows服务有问题 该服务是执行任务的计划程序。每个任务都在一个线程中执行,因此它允许用户同时执行一些任务 线程启动时,将在C#中创建一个对象(在名为C#u AUTO的vb6 dll中),并使用“New”语法。此对象的构造函数创建其他对象来执行任务。任务完成后,C_的析构函数将使用set…=没有什么。对象C_AUTO被破坏,线程也被破坏 我的问题是,当服务执行另一个任务时,另一个线程被创建为另一个C_AUTO对象。我添加了一个代码段,它在一个文件中写入内存指针的值,这些值是相同的,因此所有由C_AUTO创建的对象都不会被销毁 是否有其他方法可以加载VB6 dll而不使用“New”语法,该语法允许我在任务完成时卸载所有对象?因为几天后,服务消耗了大量内存,任务崩溃C# 4.0 c#windows服务中vb6 COM dll使用的可用内存,c#-4.0,service,vb6,C# 4.0,Service,Vb6,我对使用解决方案中引用的VB6 COM dll的windows服务有问题 该服务是执行任务的计划程序。每个任务都在一个线程中执行,因此它允许用户同时执行一些任务 线程启动时,将在C#中创建一个对象(在名为C#u AUTO的vb6 dll中),并使用“New”语法。此对象的构造函数创建其他对象来执行任务。任务完成后,C_的析构函数将使用set…=没有什么。对象C_AUTO被破坏,线程也被破坏 我的问题是,当服务执行另一个任务时,另一个线程被创建为另一个C_AUTO对象。我添加了一个代码段,它在一个
感谢您的帮助关于VB6对象,有几个令人不快的实现细节使得它们难以在C#服务中正确使用。VB6对象是单元线程化的COM对象。这是一个昂贵的词,意味着它们不是线程安全的,COM确保它们以线程安全的方式使用 C#服务几乎总是创建不适合单元线程对象的线程。COM将创建一个新线程,为这样的对象提供一个安全的家。这很昂贵,一个新线程需要1兆字节的虚拟内存 此外,只有在垃圾回收器运行时,才会卸载这样的对象(线程只会停止运行)。如果您对VB6对象进行了大量调用,但自己没有分配大量.NET对象,则很容易遇到问题。这会阻止GC频繁运行,从而避免所有这些线程被创建并占用大量虚拟内存而带来的麻烦。当你创建了大约1800个时,你会得到一个OOM-kaboom 具体的解决办法是:
- 在启动线程之前,使用Thread.SetApartmentState()方法将线程切换到STA。这会阻止COM创建该辅助线程。请注意,常见的服务技术(如使用计时器来运行服务)并不适用,您必须在OnStart()方法中创建一个线程
- 您可能需要调用Application.Run()来启动消息循环,这是STA线程的要求。这在服务中往往有点棘手,您从项目模板获得的帮助很少,无法将管道安装到位。您可以不用泵送就离开,但必须确保在创建VB6对象的同一线程上对该对象进行所有调用。错误的诊断是死锁
- 如果确定GC的运行频率不够高(使用Perfmon.exe查看.NET计数器),则可能需要帮助并调用GC.Collect()以卸载VB6对象
要把所有东西都放在这里可不是那么容易。如果您一直在考虑更新VB6代码,那么现在就是一个好时机。关于VB6对象,有几个令人不快的实现细节,使得它们难以在C#服务中正确使用。VB6对象是单元线程化的COM对象。这是一个昂贵的词,意味着它们不是线程安全的,COM确保它们以线程安全的方式使用 C#服务几乎总是创建不适合单元线程对象的线程。COM将创建一个新线程,为这样的对象提供一个安全的家。这很昂贵,一个新线程需要1兆字节的虚拟内存 此外,只有在垃圾回收器运行时,才会卸载这样的对象(线程只会停止运行)。如果您对VB6对象进行了大量调用,但自己没有分配大量.NET对象,则很容易遇到问题。这会阻止GC频繁运行,从而避免所有这些线程被创建并占用大量虚拟内存而带来的麻烦。当你创建了大约1800个时,你会得到一个OOM-kaboom 具体的解决办法是:
- 在启动线程之前,使用Thread.SetApartmentState()方法将线程切换到STA。这会阻止COM创建该辅助线程。请注意,常见的服务技术(如使用计时器来运行服务)并不适用,您必须在OnStart()方法中创建一个线程
- 您可能需要调用Application.Run()来启动消息循环,这是STA线程的要求。这在服务中往往有点棘手,您从项目模板获得的帮助很少,无法将管道安装到位。您可以不用泵送就离开,但必须确保在创建VB6对象的同一线程上对该对象进行所有调用。错误的诊断是死锁
- 如果确定GC的运行频率不够高(使用Perfmon.exe查看.NET计数器),则可能需要帮助并调用GC.Collect()以卸载VB6对象
要把所有东西都放在这里可不是那么容易。如果您一直在考虑更新VB6代码,那么现在就是一个好时机。感谢您的回复,但第一个解决方案(STA)和最后一个解决方案(GC.Collect)都不起作用。指针的id始终相同。是否有一个程序(perfom或其他)来显示程序创建的实例?感谢您的回复,但第一个解决方案(STA)和最后一个解决方案(GC.Collect)都不起作用。指针的id始终相同。是否有一个程序(perfom或其他程序)来显示程序创建的实例?