[RESOLVED] Multithreading
I'm asking this more out of curiosity than anything else, but I probably would wind up using it if I could trust it.
For me to truly embrace multithreading, I'd really like it to meet the following criteria:
- Will run equally well in the IDE as compiled. It would be far less attractive to me if this isn't met.
- Doesn't require any "separate" dependencies. In other words, it's all done with standard Windows API calls.
- Shares the same address space as the application that spawned it. I suspect that this would always be the case.
Also, until I see how it would be implemented, I'm not entirely sure what other features it could have, such as instantiating COM objects, loading forms, etc. Also, it's not clear to me how you'd tell it what functions/procedures to run in the second thread, but I think that would be more clear once the implementation was understood.
Also, obviously, it would need some kind of standard callback functions for "SuccessfullyCompleted", and "AbnormallyTerminated". Or maybe a "status" variable that's periodically checked by the primary thread would be enough.
I suppose any limits imposed on the primary thread while the secondary thread is running would have to be well understood.
Is there anything out there like this?
Best Regards,
Elroy
Re: [RESOLVED] Multithreading
Great example, Elroy! Thanks!
Soon i'll modify my approach and add the new function InitRuntime because there are numerous task when you need to service a callback function that's called from other thread.
Quote:
we must have the TypeLib
There are several workaround to bypass a TLB.
Re: [RESOLVED] Multithreading
One area which seems not to work -- whether using multiple threads, ActiveX.EXE or SharedMemory -- seems to be when trying to have the user interact at the same time other action is occurring within a control. For example:
A picturebox drawing routine where the user wants to interact with that drawing using tools.
One could move most functions for either the graphic drawing or tool usage and/or both actions (drawing and user), into different threads, ActiveX.exe or SharedMemory, but since they both interact with the same picturebox, they both need the Picturebox paint event. So some priority needs to be established so the two actions can mesh while using Paint. So does one gain any advantage
by moving the routine(s) out of the original process?
Re: [RESOLVED] Multithreading
Quote:
Originally Posted by
vb6forever
One area which seems not to work -- whether using multiple threads, ActiveX.EXE or SharedMemory -- seems to be when trying to have the user interact at the same time other action is occurring within a control. For example:
A picturebox drawing routine where the user wants to interact with that drawing using tools.
One could move most functions for either the graphic drawing or tool usage and/or both actions (drawing and user), into different threads, ActiveX.exe or SharedMemory, but since they both interact with the same picturebox, they both need the Picturebox paint event. So some priority needs to be established so the two actions can mesh while using Paint. So does one gain any advantage
by moving the routine(s) out of the original process?
Hi vb6forever,
If you look at the "SharedResources" example in the demos provided by The Trick over in his thread about DirectX9, you'll find an example of how he deals with that problem (at least in a way). He locks shared memory when the second thread is using it, and re-tries for a period of time when the locking won't work. If I remember correctly, the re-trying is done in both the primary and secondary thread. In that way, one thread gets a chance to get to a "completion" point before the other thread starts meddling with it. I'm not sure how you'd go about doing that with a PictureBox, but you could use some of the CreateEvent, ResetEvent, PulseEvent, WaitForSingleObject functions to do it.
Also, you've got to be careful when sharing objects (such as a PictureBox) across threads. Strictly speaking, the "contract" with a COM object is that only the thread that created it shall use its methods. I've played around with breaking that contract, but I'm not sure how far it can be pushed. However, when CreateThread is used, a thread is created "within the virtual address space of the calling process" (per Microsoft).
Good Luck,
Elroy
Re: [RESOLVED] Multithreading
Quote:
Originally Posted by
Elroy
Also, you've got to be careful when sharing objects (such as a PictureBox) across threads. Strictly speaking, the "contract" with a COM object is that only the thread that created it shall use its methods.
you're not completely wrong, but to clarify that's not a COM Contract. STA objects can only be instantiated within an STA, and can only be accessed from the STA they are instantiated from. Every other thread needs to use a proxy for access. That's why I recommended Curland/Krools method, because you can let the COM subsystem do the interface marshalling auto magically. Otherwise you gotta do it yourself using CoGetInterfaceAndReleaseStream as Trick pointed out.
you should try that approach out, and manually Marshal your interface to the objects you are trying to access from another thread.
Re: [RESOLVED] Multithreading
And you have to be super careful to use critical sections to protect any global data. Interlocked instructions are also very useful for shared counters. Otherwise you end up with heap corruption or non nonsensical shared counters that might not show up for hours/days/weeks depending on what your app does. I also use winapi to turn on terminate on heap corruption in anything I do that is multi threaded. In that way I at least get a crash I hopefully reproduce and take a look at in windbg.
I have also found that certain objects like scripting.dictionary require protection or weird things can happen days later.
Re: [RESOLVED] Multithreading
Quote:
Originally Posted by
vbcommander
I have also found that certain objects like scripting.dictionary require protection or weird things can happen days later.
Scripting.Dictionary is marked ThreadingModel=Apartment in registry. You cannot legitimately execute any of its methods on any other thread besides the thread that is servicing the STA its instance was created on.
Even if you try to sync your threads with critical sections (i.e. impl blocking from client-side i.e. from "outside") you cannot guarantee that the class in question is not using an hwnd for instance and GUI in Windows is single threaded by nature.
When using threading in VB6 there is no single case for critical section usage as VB6 cannot implement free threaded classes and then using instances of free threaded classes is automagically synchronized by COM apartment proxies (i.e. no manual sync needed).
cheers,
</wqw>
Re: [RESOLVED] Multithreading
You can however proxy the interface from one STA to another, if you need to access it from another thread.
If you use Krool's threading DLL, COM will do it automagically if you pass it back as IDispatch (Object) in the thread callback's Variant parameter.
Re: [RESOLVED] Multithreading
@The Trick: I saw. :) I'm on a consulting gig right now, but I'm excited to get back home and play with it. It looks really exciting.