3

I'm porting an ancient VB6 program to C#/.Net. I don't know VB6 very well and I'm asking this to understand it better.

The old VB6 program had a main course of program execution, but it also had lots of event handlers either for socket events or for timer events and the handlers for these often manipulated shared resources, e.g., common global variables, whenever they woke up and ran.

Nonetheless the old program seemed to run OK.

Trying to do this same architecture in C# is disastrous because event handlers for the socket or timers are called by the system in different threads from the main application thread and result in frequent exceptions like "The calling thread cannot access this object because a different thread owns it.", not to mention more subtle problems. Most of my work in the conversion is re-architecting the program to make it thread-safe, and eliminating the original program's heavy use of global variables.

My question is Do VB6 event handlers run in separate threads? If so how did VB6 ever get away with this? Among other things, the VB6 program had a timer that woke up every 4 seconds, manipulated some global variables and went back to sleep, while the main program was doing its thing. I can't understand why this didn't result in collisions.

Servy
  • 202,030
  • 26
  • 332
  • 449
user316117
  • 7,971
  • 20
  • 83
  • 158
  • have you considered breaking the code down into manageable pieces as well as some workable classes.. I would look at the `Telerik Code Converter` it's a free online tool that will convert VB code into C# provided it's formatted correctly.. you need to understand at least some of the working functionality in VB and then know how to convert it to C#'s equivalent hope this helps – MethodMan Nov 20 '14 at 19:32
  • 3
    VB6 was strictly [STAThread]. Same threading model as used in Winforms and WPF. – Hans Passant Nov 20 '14 at 19:34
  • I don't know what [STAThread] means in this context. I thought STAThread had something to do with COM. When an event occurs in VB6, like a timer or Socket data arrival, and the handler gets executed, is it in the same thread as the main thread of execution, and if so how is controlled transferred out of whatever was being executed at the time? – user316117 Nov 20 '14 at 19:42
  • @ DJ KRAZE Please read the title. This is a question about VB6's threading model; I'm not seeking advice about porting. – user316117 Nov 20 '14 at 19:43
  • Was? Last time I checked it has been the same for over 16 years. – Bob77 Nov 21 '14 at 15:56

3 Answers3

8

Apartment-Model Threading in Visual Basic

If you want the gritty details, research apartment threading models in COM. VB6 basically uses COM and it's built-in implicity threading models to treat single threads as message-passing entities. It simplifies thread-safety, but underneath you are sacrificing a lot of overhead by basically treating all method calls as queued service calls.

All of your code basically runs in a container that implements COM service calls. If you've ever worked with something written in VB6 in another language, you can interact with them via COM, usually.

Do VB6 event handlers run in separate threads?

Not really, because there aren't separate threads. Your code runs on a single thread, wrapped in the service-like architecture I described above. Most of what you talk to that is threaded is other COM objects which have their own apartments. So to communicate back and forth, you are basically doing RPC calls when the threads talk to each other: you aren't directly manipulating them.

Among other things, the VB6 program had a timer that woke up every 4 seconds, manipulated some global variables and went back to sleep, while the main program was doing its thing. I can't understand why this didn't result in collisions.

The "timer" is on a separate thread created for the timer, but when it calls into your code, you are guaranteed not to interrupt any other functions, because the function calls are basically queued one at a time in the thread.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Clever Neologism
  • 1,322
  • 8
  • 9
7

My question is Do VB6 event handlers run in separate threads?

Common answer: No.

Real answer: Yes, if you make nasty Win32 calls to spawn more threads. The odds of doing this correctly are close to zero. I don't think I've ever seen it in real code.

Among other things, the VB6 program had a timer that woke up every 4 seconds, manipulated some global variables and went back to sleep, while the main program was doing its thing. I can't understand why this didn't result in collisions.

When the timer wakes up, it puts a message in the UI's queue. When the UI goes idle, it processes the message and runs the event on the UI thread.

You can do the same thing in WinForms if you use the right timer.

Jonathan Allen
  • 68,373
  • 70
  • 259
  • 447
0

To Matt Wilko, DoEvents is VB6 implementing a virtual cooperative multithreading thing. What's a thread, something that can be interupted to run other code. When you use DoEvents you interupt the execution of your code, when the CPU does multithreading it preempts your code. The effect is the same. One done by VB6 runtime and one by the CPU.

The effect is the same. YOU NEED TO SYNCHRONISE ACCESS TO GLOBAL OBJECTS and VARIABLES.

Your event Handlers aren't supposed to run too long. Each event is queued and run one at a time.

Also the way to multithread a VB6 thing is to put other things in a COM Exe file with a asynchronous model. The exe calls back when finished.

  • @matt if you want to learn more see my post here. http://stackoverflow.com/questions/27153675/what-do-doeventss-in-c-sharp-actually-do/27160971#27160971 – noodlesstillalive Nov 27 '14 at 20:56