3
votes

We have very old legacy vb6 application, that has one global object that serves as Application Core, that stores different application settings, invokes database operations and so on. Multiple modules with different progid use this global object and have no problem with it due to single-thread apartment.

Not long ago new WPF application was created, that provide us transition from vb6, however it is still limited by vb6 legacy due to some architectural mistakes. It is able to connect to only one database per app instance. It hold static instance of vb6 global object in wrapper class, that serves as bridge to reach legacy functionality.

Now, we are developing new application that should not be limited by old legacy code, in particular it new application should be able to connect to several databases at once, but there is a catch: vb6 code limited to single database, so there should be several instances of vb6 global objects, one per each database.

So the question is: is it possible, and if it is, how is it possible to use several separated intstances of global vb6 objects in same C# application?

I presume that each instance of such object should live in it's own STA-Thread, but i don't know how to create such threads, that are kept alive for entire application runtime and that have assotiated wrappers, containing instances of global vb6 objects and supporting invocation of some functions from GUI thread (and how to organize such cross-thread communication, there is no thread.invoke(...)). I thinked about using wpf dispatcherization model ( wrapper class is DispatcherObject, each instance has it's own Dispatcher with it's own STA-Thread), but i cannot see how to implement such thing. Also I think it could be imlemented by loading each instance of wrapper class (static) in different AppDomains, but i don't know if it resolves STA problem for COM.

2
An interesting question. Are you sure it wouldn't be less trouble (and more reliable, easier to maintain, etc) to just recode the vb6 global object in c#?Robert Harvey
We cannot just recode vb6 global code because we will have to recode every vb6 module that use it - and it's a lot of work (and nobody even wants to touch it, it would much easier to rewrite these modules in C# from scratch. But it's also will take a long time, so we are trying to achieve bacward compatibility with old modules in new application)Aloraman
This is a built-in capability of VB6. If you configured it correctly then creating the Application object again should start another instance of the out-of-process server. Completely isolated from the first, it can talk to its own database.Hans Passant
Threads aren't the only issue. Threads are not independent from each other. Code running on two different threads may still use common memory, if the code was written to assume there is only one thread.John Saunders
You might get away with running one instance of the global object per AppDomain. To be safe, you should run them each in their own process, since that's the assumption they were created with. I guarantee you that horrible things can happen when you violate the assumptions of ancient code - especially when you introduce them to things which simply did not exist when they were written.John Saunders

2 Answers

1
votes

It is possible, using what is referred to as unmanaged code. Check out this: http://www.codeproject.com/Articles/154144/Using-Unmanaged-VB6-Code-in-NET

0
votes

You might get away with running one instance of the global object per AppDomain.

To be safe, you should run them each in its own process, since that's the assumption they were created with. I guarantee you that horrible things can happen when you violate the assumptions of ancient code - especially when you introduce them to things which simply did not exist when they were written.