混合VB6“遗留代码”和一个网络应用程序
我正在开发一个新网站,使用 ASP.NET MVC2 用 VB.Net 编写,需要为各种复杂的业务逻辑调用“遗留”VB6 代码。 VB6 是一个由许多 dll 组成的框架,并且是有状态的,我们几乎模拟了该框架在客户端应用程序中的使用方式,即应用程序运行(大量状态设置)、用户登录(甚至更多状态)以及然后加载一个文件(甚至更多状态)。
我已经获得了一个“Web 服务接口框架”来启动并运行它以在 Web 应用程序中使用,这个“Web 框架”将遗留代码隐藏在 IIS 下运行的薄层后面。这个想法是IIS提供的线程池将减少内存使用等等。我不禁相信提供这个的人错过了重点,因为每个实例都是有状态的,所以线程池无法工作,因为一旦用户使用池中的一个特定对象登录,其他对象将无法为该客户端提供服务(因为它不具有状态)!此外,与直接调用对象相比,添加 Web 服务接口和关联的 SOAP 编组是巨大的开销。
我能想到的唯一方法是,要么使用单个遗留接口实例,该实例由所有客户端使用,并被每个调用阻塞直到完成,要么每个客户端一个线程,每个遗留接口对象在新线程中创建并生存客户的生活。
这些都不是理想的,但考虑到有问题的代码量以及向 .net 的长期迁移计划(2 年以上且仍然有状态),我想不出替代方案。我们在 Citrix 环境中为某些客户运行原始客户端应用程序,因此我希望在给定足够强大的服务器的情况下,每个客户端的线程也可以正常运行,并且框架本身的开销应该低于涉及客户端应用程序时的开销。
有什么想法吗?
I'm working on a new website, written in VB.Net using ASP.NET MVC2, there is a need to call "legacy" VB6 code for various complex bits of business logic. The VB6 is a framework consisting of many dlls and is very stateful, we are pretty much emulating how the framework is used in our client application, ie the application runs (lots of state setup), a user logs on (even more state) and then loads a file (even more state).
I've been provided with a "web service interface framework" to get this up and running for use in the web app, this "web framework" hides the legacy code behind a thin layer running under IIS. The idea being that thread pooling provided by IIS will reduce memory use etc etc. I can't help but believe that the guy who provided this has missed the point, since each instance is so stateful there is no way that a thread pool can work, since once a user logs on using one particular object from the pool, no other object will be capable of servicing that client (since it wont have the state)! Also, adding a web service interface and associated SOAP marshalling is a huge overhead compared to calling the objects directly.
The only way I can think of doing this is either a single legacy interface instance which is used by all clients and blocked by each call until it completes, or a thread per client with each legacy interface object being created in a new thread and living for the life of the client.
None of these is ideal but with the amount of code in question and the prolonged migration programme to .net (2+ years and still stateful) I can't think of an alternative. We run the original client app in a citrix environment for some customers so I expect that it could also run ok with thread per client given a beefy enough server and that the overheads of the framework itself should be lower than when the client app is involved.
Any ideas??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议你看一下这个框架 Visual WebGui。我是这家公司的一名员工,因此听起来并不客观,但我相信 Visual WebGui 已经解决了扩展有状态应用程序并将单用户环境转变为多用户环境的一些主要问题。值得一看。
I suggest that you take a look at this framework Visual WebGui. I am an employee with this company and therefore wouldn’t sound objective but I believe Visual WebGui had solved some of the major issues with scaling statefull applications and turning single user environment into multi user environment. Worth a look.
这是一个选择,但它不会很漂亮。
听起来您需要将一个长期存在的对象(后端层的有状态对象)与单个用户相关联。
您可以将此对象存储在应用程序状态中,并使用键将其与用户会话状态关联起来。您需要提供一个包装器来跟踪它们。当会话终止时,您可以捕获事件并销毁后端对象。
应用程序状态是一个键/值存储,就像会话一样。您可以通过 HttpContext.Application 进行访问。
最大的缺点是您放入其中的对象会一直存在,直到您销毁它们,因此您的包装器和会话销毁代码需要准确无误。除此之外,这可能是一种快速启动和运行的方法。
就像我说的,它不会是最佳的,但它可能会起作用。
有关影响的更多信息:
http://msdn.microsoft.com/en-us /library/bf9xhdz4(VS.71).aspx
编辑:
您也可以在网络场环境中进行此工作。在会话状态中存储重新创建有状态遗留对象所需的信息,这些信息可以使用内置 SQL 提供程序在计算机之间共享。如果用户跳到不存在该对象的服务器,您的应用程序状态包装器可以从会话状态信息重新创建它。
只剩下如何清理服务器上不需要的有状态对象了。在您的检索包装器中,每次访问给定的有状态对象时都会更新哈希表或具有访问时间的内容。在包装器中设置定期清理例程,销毁自 Web 应用程序的会话超时值稍长以来尚未访问过的有状态对象。
Here's an option but it won't be pretty.
It sounds like you need to associate a long lived object (the stateful object to your backend tier) with individual users.
You could store this object in Application state and associate it with the users Session state with a key. You'd need to provide a wrapper to keep track of them all. When the session dies you could capture the event and destroy the backend object.
Application state is a key/value store just like Session. You can access through
HttpContext.Application
The big downfall to this is that the objects you put in there stick around until you destroy them so your wrapper and session destroying code need to be spot on. Other than that this might be a quick way to get up and running.
Like I said, it won't be optimal, but it'll probably work.
More info on implications:
http://msdn.microsoft.com/en-us/library/bf9xhdz4(VS.71).aspx
EDIT:
You could also make this work in a web farm environment. Store the information needed to recreate your stateful legacy object in Session state which can be shared between the machines using the built in SQL Provider. If a user bounces to a server where the object doesn't exist your Application state wrapper can just recreate it from the Session state info.
This just leaves how to clean up the stateful object on servers where it isn't needed. In your retrieval wrapper update a hashtable or something with the access time each time the given stateful object is accessed. Have a periodic cleanup routine in th wrapper detroy the stateful objects that haven't been accessed since a little more than the session timeout value of your web app.