Threads and Delegates

L

Lior Amar

Quick question about threads and delegates.

I have the following scenario

Thread A (CLASSA) spawns Thread B (CLASSB) and passes it a DelegateA to a
callback
Thread B Invokes a DelegateB asynchronously (could be a timer but then we
get Thread C)
Upon completion of DelegateB, Thread B would like to callback ThreadA using
DelegateA but as we all know the call to DelegateA is running in ThreadB. Is
there anyway to get Thread B to call a method in Thread A.

My Problem is that I need to notify a single threaded COM object that work
has been completed. I can do this by raising an event to that COM object but
if that Object tries to use any pointer that he currently has then POW(which
makes sense).

I've coded something very similar in C++ and am wondering if this can be
done from VB.NET? Otherwise I'll just port my C++ code to V7.

Thanks,

Lior
 
S

steve

an easier route may just be to have threadB raise an even when it is
finished doing whatever you created it to do. that way maintaining the code
would be a bit easier as threadA is responsible for creating threadB,
assigning a delegate in threadA to handle the "done()" event in threadB, and
for tearing threadB down.

think about consolidating.

hth,

steve
 
M

Mattias Sjögren

Lior,
Quick question about threads and delegates.

I have the following scenario

Thread A (CLASSA) spawns Thread B (CLASSB) and passes it a DelegateA to a
callback
Thread B Invokes a DelegateB asynchronously (could be a timer but then we
get Thread C)
Upon completion of DelegateB, Thread B would like to callback ThreadA using
DelegateA but as we all know the call to DelegateA is running in ThreadB. Is
there anyway to get Thread B to call a method in Thread A.

Does Thread B do anything else but invoke Delegate A? If not, why
don't you do it directly from Thread A?

If that's not possible, but Thread A is a GUI thread, you could
consider using Control.Invoke on some control created on that thread.
If it's not a UI thread, perhaps using an AutoResetEvent or
ManualResetEvent would be better.



Mattias
 
L

Lior Amar

Raising an event back to Thread A from Thread B is the equivalent of having
the delegate. The event will be caught by CLASSA but it will be on Thread B.
My challenged then is still to re-enter Thread B.

It was one of the first thing I tried...Wouldn't it have been so nice to be
that simple :) I've been going at this for 2 days now trying to figure out
how to re-enter thread A.

Thanks for the help though,

Lior
 
L

Lior Amar

I had found the samples for the Form.BeginInvoke and was hoping there was
something like that for objects with no UI. Can't have them run on a single
thread because it's invoking resources on different machines. I actually
have a lot more then two threads running at any given point. Was hopping not
to do a Singleton using remoting but that seems to be the way I'm leaning
now.

I'm kind've stuck trying to make this work with the Single Threaded COM
object so I need the Main entry point thread to be the one that notifies it.
We all know what happens if you call STA COM objects across thread
boundaries. The explosions are spectacular :)

What's the hardest thing about synchronizing threads? Marshaling and that's
not very difficult. I'm Finding that .NET simplifies threading so much that
something that used to be simple is kind've elusive.

Thanks for the suggestions,

Lior
 
S

steve

thread.join

Lior Amar said:
Raising an event back to Thread A from Thread B is the equivalent of having
the delegate. The event will be caught by CLASSA but it will be on Thread B.
My challenged then is still to re-enter Thread B.

It was one of the first thing I tried...Wouldn't it have been so nice to be
that simple :) I've been going at this for 2 days now trying to figure out
how to re-enter thread A.

Thanks for the help though,

Lior

to
 
L

Lior Amar

Thread.Join = Blocks the calling thread until a thread terminates.

Am I missing something? How does that allow me to re-enter my thread?
 
P

Peter Huang [MSFT]

Hi Lior,

Here are two KB links, you may have a look.
816161 HOW TO: Synchronize Access to a Shared Resource in a Multithreading
http://support.microsoft.com/?id=816161
816160 HOW TO: Synchronize the Access to a Shared Resource in a
Multithreading
http://support.microsoft.com/?id=816160

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
From: "Lior Amar" <[email protected]>
References: <[email protected]>
Subject: Re: Threads and Delegates
Date: Fri, 26 Sep 2003 07:28:28 -0400
Lines: 58
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.languages.vb
NNTP-Posting-Host: ostnet.net 66.201.203.233
Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.vb:141492
X-Tomcat-NG: microsoft.public.dotnet.languages.vb

I had found the samples for the Form.BeginInvoke and was hoping there was
something like that for objects with no UI. Can't have them run on a single
thread because it's invoking resources on different machines. I actually
have a lot more then two threads running at any given point. Was hopping not
to do a Singleton using remoting but that seems to be the way I'm leaning
now.

I'm kind've stuck trying to make this work with the Single Threaded COM
object so I need the Main entry point thread to be the one that notifies it.
We all know what happens if you call STA COM objects across thread
boundaries. The explosions are spectacular :)

What's the hardest thing about synchronizing threads? Marshaling and that's
not very difficult. I'm Finding that .NET simplifies threading so much that
something that used to be simple is kind've elusive.

Thanks for the suggestions,

Lior


Mattias Sjögren said:
ThreadB.
 
L

Lior Amar

Hey Peter,

Thanks for the links but these explain more on shared resources. Not really
having issues with multi-threading as is. More interested on making my
thread reentrant. Tried even overriding marshalling but nothing doing. Super
simple to thread in .NET but man is it tough to re-enter a thread. I know it
can be done with a Form/Component with the BeginInvoke. Tried that with
delegates but it doesn't do it. Did learn that if you try enough Async
delegate invokation that sooner or later the delegate call will be made on a
different thread also. Also found that you can make recursive
delegates....not recommended though

Whatever approach I take, I can not get the call to reenter my initial
thread. I'm doing this with C++ and an ATL component but I would rather a
complete VB.NET solution.

Things I've tried so far:

1. Delegates
2. Shared Resources
3. Inheriting the RealProxy and Implementing the IRemotingTypeInfo to try
and create a Single Threaded object using MarshalByRefObject.
4. ContextBoundObject
5. Sacrificing a small animal

Best results so far have been with #5

I've pretty much just gone with my C++ workaround but plan on working on it
more on my free time. It just seems like something that shouldn't be that
difficult!

Any ideas on what else I should try...Would love to know what the
Form/Component.BeginInvoke does to reenter it's thread

Thanks,

Lior

Peter Huang said:
Hi Lior,

Here are two KB links, you may have a look.
816161 HOW TO: Synchronize Access to a Shared Resource in a Multithreading
http://support.microsoft.com/?id=816161
816160 HOW TO: Synchronize the Access to a Shared Resource in a
Multithreading
http://support.microsoft.com/?id=816160

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
 
P

Peter Huang [MSFT]

HI Lior,

Did the Thread A have a UI?
If so, I think you use the STA modal in the thread A.
Did you block the thread A with such function as waitone and etc.?
If so, the thread A which is a STA will be blocked and will no longer get
messages,i.e. the message pump will stop.
Did I misunderstand your meaning?

To workaround the problem, I think you may open a form in the thread A,
which will be running and receive message.

Did I misunderstand your meaning?
If you have any question, please feel free to let me know.

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
From: "Lior Amar" <[email protected]>
References: <[email protected]>
<ehuG#[email protected]>
 
Z

Zane Thomas [.NET/C# MVP]

Lior,
My Problem is that I need to notify a single threaded COM object that work
has been completed. I can do this by raising an event to that COM object but
if that Object tries to use any pointer that he currently has then POW(which
makes sense).

How did the COM object get pointers that it shouldn't be using? If you create
objects in ThreadB and pass them to ThreadA then you will have to marshall them.





--
What the caterpillar calls the end,
the rest of the world calls a butterfly.
~ Lao-tzu

Components For Thinkers
www.abderaware.com
zane @at@ abderaware .dot. com
 
L

Lior Amar

Hey Peter,

There is no UI for this question. In essence you create a ClassLibrary that
has three classes. The main Class will spawn two threads and have the other
two classes run in those threads. The Main class will instantiate other
objects that it will use to accomplish its functionality. It will pass along
a delegate to the other two threads to be notified when their work is
complete. Once the delegate gets shot off, it will raise an event to a COM
object that is running on the same thread. Now rules are simple with COM
objects. If you raise an event to a COM object that is STA, the event origin
MUST be in the same thread otherwise the COM object will be able to receive
the message but as soon as it tries to access memory address that are on
that threads stack it will EXPLODE. So I need to figure out how to re-enter
my Main thread when one of the children threads has completed.

So no UI but the same notions. I also know that the BeginInvoke on a
component or form will do exactly what I'm trying to do.

Thanks,
 
L

Lior Amar

If the COM object lives in ThreadA and has a pointer to ClassA then as soon
as it receives an event from Class A on Thread B it will have invalid
pointers. Class A on thread A receives a delegate callback from Class B on
thread B and then raises an event or calls a callback. Since the delegate
lives on the ThreadB then the callback will also live on Thread B which is
the problem.

If You have an STA component that is a bottleneck what you do is create an
FTA component that funnels all calls back to the STA from the Main thread.
Forces you to be more vigilant about thread synchronization but allows you
to spawn as many worker threads as necessary while still maintaining an STA
environment. Useful when working with UI's.

Thanks,

Lior
 
Z

Zane Thomas [.NET/C# MVP]

Lior,

The 'traditional' way to handle that sort of problem is to send a window message
from ThreadB to ThreadA. Have you thought about trying something like that, or
some other IPC mechanism?


--
What the caterpillar calls the end,
the rest of the world calls a butterfly.
~ Lao-tzu

Components For Thinkers
www.abderaware.com
zane @at@ abderaware .dot. com
 
P

Peter Huang [MSFT]

Hi Lior,

Have you tried zane's suggestion? It seems that the main problem is that
you wants to notify Thread A from Thread B.

I suggest you use a global variable, when the Thread B wants to tell Thread
A that something has done, Thread B can set the global variable to a
specific value. In Thread A, you can evaluate if the global variable has
been set to the specific value, if so you can notify COM Object in Thread
A.

Regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
From: "Lior Amar" <[email protected]>
References: <[email protected]>
<ehuG#[email protected]>
<#[email protected]>
<[email protected]>
 
L

Lior Amar

It's the way I go about it with my C++ component. PostThreadMessage with the
the correct thread ID and handle it in the previous thread. If I need to
pass lots of data then I normally use pipes that have been negotiated at the
beginning. Was hoping this would be simpler in .NET but I'm guessing
underneath all that window dressing it's still windows.

Thanks for all the help...I will go with my C++ component that does it very
elegantly. It was just driving me nuts because it's so simple to do if you
have a UI. Everything is in place for that

Thanks,

Lior
 
L

Lior Amar

Hey Peter,

Like I was telling Zane...If I go with that route, then I'll just stick to
the C++ component I have that does it a lot more elegantly. I was really
hoping I was missing something cause it's so easy to do if you have a UI.
I'm simply more interested in figuring out how to go about it while using
the platforms advantages. If I can only get a glimpse at the BeginInvoke
code from a form or component.

Thanks for all the help,

Lior
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top