从多线程 C# Windows 服务应用程序调用 VB6 DLL?
我正在运行需要调用 VB6 dll 的多线程 Windows 服务。 没有关于此 VB6 dll 的文档,并且此遗留系统支持非常关键的业务流程。
第一次(第一个线程),这个 dll 表现良好。 当其他线程需要访问时,它开始提供错误的结果。
我读到一个人说:
“如果您使用 VB6,请注意一件事。您的线程 如果您是,则必须更改模型以支持公寓 运行多线程服务。 VB只支持多个 单线程单元,但 .NET 运行完全免费的线程 通常情况下。 调用 VB6 DLL 的线程需要是 与 DLL 兼容。”
团队的另一个人给了我这个想法,将这个 ddl 放在一个单独的应用程序域中。但我不确定。
我们如何使用从多线程 c# windows 服务应用程序调用的 VB6 dll?
I'm running a multithreaded windows service that need to call a VB6 dll. There's no documentation about this VB6 dll and this legacy system supports a very critical business process.
At first time (1st thread), this dll performs well. As other threads need access, it start provide wrong results.
I read one guys saying:
"Just be careful of one thing if you are using VB6. Your threading
model is going to have to change to support apartments if you are
running a multithreaded service. VB only supports multiple
single-threaded apartments, but .NET runs fully free threaded
normally. The thread that calls into the VB6 DLL needs to be
compatible with the DLL."
Another guy from team gave me the idea to put this ddl in a separated application domain. But I'm not sure.
How can we work with VB6 dll called from a multithreaded c# windows service application?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这篇关于多线程 Visual Basic 6 DLL 的文章提供了一些见解。 它说:
这篇文章说有三种可能的模型选择:
我假设默认为
一个执行线程
,并且需要选择其他两个选项之一。This article on multithreading Visual Basic 6 DLL's provides some insight. It says:
This article says there are three possible models to choose from:
I assume that the default is
one thread of execution
, and that one of the other two options needs to be selected.您可能想看看这个: linky
这里是引起我注意的一个片段:
You might want to take a look at this: linky
And here is a snippet that caught my attention:
当线程进入时,您是否保存对象并稍后在新线程上重用它们? 如果可以的话,为每个线程创建新鲜的对象。 我们使用的数据层 dll 就遇到过这样的情况。 如果您在一个线程上创建连接,则无法从另一个线程使用该连接。 如果您在每个线程上创建一个新连接,它就可以正常工作。
如果创建对象的速度很慢,请查看 ThreadPool 类和 ThreadStatic 属性。 线程池一遍又一遍地回收同一组线程来完成工作,而 ThreadStatic 允许您创建仅针对一个线程存在的对象。 例如,
当收到请求时,将其转换为作业并将其放入线程池中。 作业启动时,检查静态对象是否初始化;
When the threads come in, are you saving objects and reusing them later on new threads? If you can, create the objects fresh for every thread. We have a situation like this with a data layer dll we use. If you create a connection on one thread, it can't be used from another. If you create a new connection on each thread, it works fine.
If it's slow to create your objects, look at the ThreadPool class and the ThreadStatic attribute. Threadpools recycle the same set of threads over and over to do work, and ThreadStatic lets you create an object that exists for one thread only. eg
As a request comes in, turn it into a job and queue it in your thread pool. When the job starts, check if the static object is initialised;
你说
同时你说
我非常确定管理层意识到您所看到的失败,因为支持关键业务流程的代码是旧的且没有记录,并且正在以从未打算使用的方式使用,并且从未经过测试使用。 我敢打赌,以前从未测试过它可以在 .NET 中使用,不是吗?
这是我的建议,这与我实际实现的类似:
VB6 DLL 期望在单个线程上调用。 不要失望!当你的服务启动时,让它启动一个适当类型的线程(我不能说,因为我故意忘记了所有 STA /MTA 的东西)。 将对该线程的访问 VB6 DLL 的请求排队。 让所有此类访问都通过单线程进行。
这样,就 VB6 DLL 而言,它的运行方式与测试时的运行方式完全一样。
顺便说一句,这与我实现的略有不同。 我有一个 Web 服务,而不是 Windows 服务。 我有一个 C DLL,而不是 VB6,也不是 COM。 我只是将对事物的所有访问重构为一个类,然后在每个公共方法周围放置锁定语句。
You say
and at the same time you say
I'd make very certain that Management is aware of the failure you're seeing because the code supporting the critical business process is old and undocumented, and is being used in a way it was never intended to be used, and was never tested to be used. I bet it's also never been tested to be used from .NET before, has it?
Here's my suggestion, and this is similar to something I've actually implemented:
The VB6 DLL expects to be called on a single thread. Do not disappoint it! When your service starts, have it start up a thread of the appropriate type (I can't say, since I've deliberately forgotten all that STA/MTA stuff). Queue up requests to that thread for access to the VB6 DLL. Have all such access go through the single thread.
That way, as far as the VB6 DLL is concerned, it's running exactly as it was tested to run.
BTW, this is slightly different from what I've implemented. I had a web service, not a Windows Service. I had a C DLL, not VB6, and it wasn't COM. I just refactored all access to the thing into a single class, then put lock statements around each of the public methods.