Worker threads in vb apartment activex dlls

I want to create a worker thread that processes incoming messages to update a cache. However, I know that cross thread calls to activeX objects need to be marshalled between apartments - say if globals are used in the dll. However, I'm not creating another apartment, do I still need to marshal calls to objects on the apartment thread.
Basically I have a global collection object that is accessed by the apartment, and I want to create a worker thread that updates this collection as messages come in. If I use synchronisation objects on each update of the collection, I guess this will cause the apartment thread to hang while I block access to the collection - will vb be able to cope with this?
jimshortAsked:
Who is Participating?
 
VBGuruConnect With a Mentor Commented:
Nice to know it helped you.
0
 
caraf_gCommented:
> Whoosh...

> What was that?

> That was the sound of that question going straight over my head.

But I'm interested, so I'm posting a comment that will enable me to read the contents of this thread after it's been answered. I hope it will be answered satisfactorily.

I would be surprised if globals from one apartment were in any way accessible by other apartments, but as the above suggests, I know very little about threading so I can't state this with any certainty.

What exactly is a synchronisation object?
0
 
DragonWolfCommented:
ditto
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
GordonpCommented:
I dont think it can be done. With apartment threading each thread has its own copy of the Global data, and there is no interaction between the two.

therefor if you update your collection in one thread, the "same" collection in the other thread would be unaffected.

You said in your question, that your not creating another apartment, but you can only have one thread per apartment, so where are you getting your second worker thread. Or like the other two has this question gone right over my head too.

Gordon
0
 
jimshortAuthor Commented:
ActiveX dll, has global ref to an object of type Cache which is externally exposed.

in class_initialise of Cache object have

set gCache = Me

(will need
public sub Cache_Clear
Set gCache = nothing
end sub

public sub Cache_Init
use createthread api call to create a thread, pass in function
Public sub ReadMsgQMessages
   Loop until get quit notification, getting messages. If message, call createmutex/createcriticalsection or something, do
gCache.Item(strKey).Dirty = True
destroymutex (or whatever synchronisation object I need)

There can only be one thread in an apartment, this is true, but does com know about this thread? Does windows prevent creating new threads once OLEInitialise has setup the main thread as apartment?

I know that if I create another thread and then call OLEInitialise - this creates an apartment in the com libraries, and any objects created using CoCreateInstance will be created on this thread - but I'm not doing this, I'm just spawning a thread that (in a supposedly thread safe manner) is accessing objects in an apartment - the com libraries know nothing about it - this is what worries me.

It is basically a hack to have 2 threads in an apartment, but before I go ahead and spend time doing it, I need to know if it's going to work :)
0
 
GustavoValdesCommented:
You could do this using two projects, one in which you could store the data that both threads will share, but this project must be defined with a Thread Pool = 1, this will garantee that all the objects created within it will be in the main Single Threaded Apartment.
Then when you access this data from one thread or the other from your multithreaded program, you can be sure you're working with the same copy of the global data.
0
 
VBGuruCommented:
0
 
GordonpCommented:
If you use CreateThread then Com does not know about it and it wont create an apartment.

However if you use VB6 then you cannot use CreateThread and in VB5 its unstable to say the least, but if you can make it work then Ok.

If you use seperate threads like this then use Mutex's will only block the thread rather than the apartment.

If you go with Gustavo's answer you'll still need to implement some form of synch.

Gordon
0
 
jimshortAuthor Commented:
Gustavo

I want it to be inprocess dll - there will be quite a bit of overhead on the cache access from the creator of the cache. The cache updator will not be calling that much though, so I can marshal across there. Thread pooling is used for out of process components. And indeed they will use the same global data as they are on the same thread, but that thread is out of process.

Gordon

I think mutex's/critical sections block sections of code from running, rather than any particular thread. Mutex's work cross process, whereas critical sections are with process.
The thing I need to do is follow com rules and marshall across the threads.

VBGuru, you have answered the question, the content on that page is excellent and confirms my worries about not marshalling the thread.
I think I'm going to do it in C++ using free threading with the freethreaded marshaller so my vb app can call it with no marshalling overhead. It is a fairly simple dll, so won't be too tricky to do in ATL

Thanks folks, - if you answer this VBGuru, you get the prize :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.