By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,742 Members | 1,044 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,742 IT Pros & Developers. It's quick & easy.

Thread A notifying Thread B of an Event

P: n/a
Using VS 2003, VB, MSDE...

There are two threads, A & B, that continously run and are started by Sub
Main. They instantiationsl of identical code. Thread A handles call
activity on telephone line 1 and Thread B handles call activity on telephone
line 2. They use a common SQL datasource, but all DataSets are unique to
each thread.

Is there a way for thread A to occasionally communication to thread B that
something has happened? The ideal situation would be for thread A to raise
an event that a handler in thread B handles. But, I don't see how to do
that (the raised event would be handled "up the call stack" in Sub Main, not
"horizontially" by the other thread).

Specifically, thread A has added a row(s) to the common datasource that I
need thread B to know about. I am currently doing it with a timer in thread
B that check the common datasource for changes every 15 seconds, which works
OK, but am looking for a simpler solution. I have looked at SQL triggers,
but don't see how that would alert thread B. I have looked at RaseEvents,
but don't see any help there either.

Any ideas? Do System.Timers. exert a heavy resource usage toll? If not I
may jus stick with the timer method.

Thansk!

Bob
Nov 20 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a

"Bob Day" <Bo****@TouchTalk.net> wrote in message
news:ub****************@TK2MSFTNGP12.phx.gbl...
Using VS 2003, VB, MSDE...

There are two threads, A & B, that continously run and are started by Sub
Main. They instantiationsl of identical code. Thread A handles call
activity on telephone line 1 and Thread B handles call activity on telephone line 2. They use a common SQL datasource, but all DataSets are unique to
each thread.

Is there a way for thread A to occasionally communication to thread B that
something has happened? The ideal situation would be for thread A to raise an event that a handler in thread B handles. But, I don't see how to do
that (the raised event would be handled "up the call stack" in Sub Main, not "horizontially" by the other thread).

You can use addhandler... If you remember from your thread creation you
have something like

Dim ThreadA as new System.Threading.thread(AddressOf myClass.MyFunctionA)
Dim ThreadB as new System.Threading.Thread(AddressOf myClass.MyFunctionB)

now these act like any other class... Which means you can raisevents and
hook between threads (a lot of us design this way, how do you think we make
data intensive UI's so damn quick.=))

So, all those events in A are availible in B through your class
declaration... say classA has eventA and classB has eventB...

So.. lets try this.

sub main()

dim classA as new myClassA
dim classB as new myClassB

AddHandler classA.eventA, New EventHandler(AddressOf classB.onEventA)
...thread starting...

end sub

ClassB.onEventA is a matching eventhandler to the class A event (I just
used an argumentless event handler delegate (thats what EventHandler is...)

Delegates ensure communication across threads... (one of there many useful
purposes)

And thats about it...

HTH,
CJ
Specifically, thread A has added a row(s) to the common datasource that I
need thread B to know about. I am currently doing it with a timer in thread B that check the common datasource for changes every 15 seconds, which works OK, but am looking for a simpler solution. I have looked at SQL triggers, but don't see how that would alert thread B. I have looked at RaseEvents,
but don't see any help there either.

Any ideas? Do System.Timers. exert a heavy resource usage toll? If not I
may jus stick with the timer method.

Thansk!

Bob

Nov 20 '05 #2

P: n/a
Thanks for your help, but I am afraid I am going to need far more
explaination. I have played with your comments for some time now, and
cannot get them to work in any meaningful way.

I have no problem with Raising an event that is caught higher up in the call
stack. But raising an event in one thread caught by a 2nd thread handler
simply isn't working as expected.

Question: If thead A raises an event caught by thread B, I would expect the
delgate to be running on thread B . But debug inidcates that thread A is
running the delagate on thread B. Is this correct? This will present a
host of problems.

Can you reference a URL or more detailed areticles on this issue? I have
searched MSDN, and have not come up with sample code or a good explaination.
Any type of sample code the works would be appreciated.

Thanks!

Bob
"Bob Day" <Bo****@TouchTalk.net> wrote in message
news:ub****************@TK2MSFTNGP12.phx.gbl...
Using VS 2003, VB, MSDE...

There are two threads, A & B, that continously run and are started by Sub
Main. They instantiationsl of identical code. Thread A handles call
activity on telephone line 1 and Thread B handles call activity on telephone line 2. They use a common SQL datasource, but all DataSets are unique to
each thread.

Is there a way for thread A to occasionally communication to thread B that
something has happened? The ideal situation would be for thread A to raise an event that a handler in thread B handles. But, I don't see how to do
that (the raised event would be handled "up the call stack" in Sub Main, not "horizontially" by the other thread).

Specifically, thread A has added a row(s) to the common datasource that I
need thread B to know about. I am currently doing it with a timer in thread B that check the common datasource for changes every 15 seconds, which works OK, but am looking for a simpler solution. I have looked at SQL triggers, but don't see how that would alert thread B. I have looked at RaseEvents,
but don't see any help there either.

Any ideas? Do System.Timers. exert a heavy resource usage toll? If not I
may jus stick with the timer method.

Thansk!

Bob

Nov 20 '05 #3

P: n/a
Hi Bob,

A queue is the preferred way to send data across free-thread boundaries.
There is an online chat that has discussion of this on:
http://msdn.microsoft.com/chats/vstu...dio_041602.asp

Alan Dennis book, .NET Multithreading does quite a good job of explaining
this, and provides example code. You can get information from the publisher
at www.manning.com -- the books is available in both print and eBook
versions.

Dick
--
Richard Grier (Microsoft Visual Basic MVP)

See www.hardandsoftware.net for contact information.

Author of Visual Basic Programmer's Guide to Serial Communications, 3rd
Edition ISBN 1-890422-27-4 (391 pages) published February 2002.
Nov 20 '05 #4

P: n/a
Hi Bob,

Thanks for posting in the community.

First of all, I would like to confirm my understanding of your issue.
From your description, I understand that you have two threads, and you hope
thread A will tell thread B that something has been done.
Have I fully understood you? If there is anything I misunderstood, please
feel free to let me know.

Based on my experience, if the event handler is on thread A, it will be
fired on Thread A and will not on thread B. To achieve your aim, the Timer
will be a good solution, also you may try to use the .net framework buildin
synchronized object.
e.g. Mutex.
You can wait for the Mutex in Thread B, and after the Thread A has done
something, thread A will realease the mutex and then thread B which is
waiting for the object return and the Thread B will run continuely.

Synchronizing Data for Multithreading
http://msdn.microsoft.com/library/de...us/cpguide/htm
l/cpconmanagedthreadingsupport.asp

Mutex
http://msdn.microsoft.com/library/de...us/cpguide/htm
l/cpconmutex.asp
Best 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.

Nov 20 '05 #5

P: n/a
Based on my experience, if the event handler is on thread A, it will be
fired on Thread A and will not on thread B. To achieve your aim, the Timer
will be a good solution,
A Timer? How on earth did you get a job at MS Peter? I swear your
"solutions" are the most ill thought out ideas on the planet. Again, you
have completly missed the point on this dicussion and have offered nothing
valuable to add to it.
also you may try to use the .net framework buildin
synchronized object.
e.g. Mutex.
I don't believe synchronization was what he was asking....
You can wait for the Mutex in Thread B, and after the Thread A has done
something, thread A will realease the mutex and then thread B which is
waiting for the object return and the Thread B will run continuely.

Synchronizing Data for Multithreading
http://msdn.microsoft.com/library/de...us/cpguide/htm l/cpconmanagedthreadingsupport.asp

Mutex
http://msdn.microsoft.com/library/de...us/cpguide/htm l/cpconmutex.asp
Best 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.

Nov 20 '05 #6

P: n/a
Cor
Hi CJ,

I have read it 10 times (the problem) I did that because it is for Peter
difficult to defend himself. I think that a timer is in this case one of the
solutions (and in my eyes even the best).

The main difficult is the problem description, in my opinion it starts with
bringing us probably on the wrong leg. It is telling about a common
datasource, probably meant with that the database while we are using the
word common datasource for something else (not that it is used wrong, but
just because we are using it mostly in another meaning)...

Than it is for the rest one solution which uses in every thread its own
datatables completely separated as well in the database as in the datasets
(it are 2 lines, but if it where hundred it was the same in my idea)

Then there is a horizontal event necessary, and that is weird, in this
situation, there is no need for line 1 to see activity on line 2 and visa
versa (think that it would be 100lines).

The main program can be used to keep track on the activities time by time by
information given to it from the threads. (Not told that it should, this is
just guessing).

For that is a timer very good usable in my idea.

And I do not think that Peter's sollution are that bad, he is given them
mostly on not answered threads and therefore he has probably to guess a lot.

Cor
Nov 20 '05 #7

P: n/a
Cor,
Hi CJ,

I have read it 10 times (the problem) I did that because it is for Peter
difficult to defend himself. I think that a timer is in this case one of the solutions (and in my eyes even the best).

Timers just seem to be wasted time on the CPU. Not the time they take to
iterate (because I know they sleep their thread until its time to raise the
tick). But to constnatly parse through your data tables to notice if there
is a change seems HIGHLY inefficient.

As for horizontal events, I don't see this as being a big problem. Now,
maybe I didn't explain myself well enough, I don't know. But look at it
this way.

In order to work horizontally, ThreadA needs to know the existance of
ThreadB and ThreadB needs to know the existance of threadA. So you can do
this with simple object references. Obviously, some thread has to start
both A and B (they just can't start out of no where) so that can place a
property in A and a property in B to be references back to the opposite
class that is running the method on a separate thread.

Now, since we have both references within the object (even though they are
running on different threads) we can still hook the events to that
particular instance, then use a delegate to bring it over the thread boundry
to update the dataset on the opposing thread.

So, what are we supposed to hook? Well, internally in each class you could
tell it to hook the rowchanged/rowchanging event on a datatable, then define
your own event to hook between the threads (to send additional data if so
desired).

Then on the actual methods that process the changes, do whatever you want
within that separated thread.

Now, does this work on 100 lines? Sorta, it requires a little more work to
make it work properly, but that wasn't the question at hand now was it.
Same concept though, except you could use the main thread to do the
delegating...

But a timer? come on Cor...

The main difficult is the problem description, in my opinion it starts with bringing us probably on the wrong leg. It is telling about a common
datasource, probably meant with that the database while we are using the
word common datasource for something else (not that it is used wrong, but
just because we are using it mostly in another meaning)...

Than it is for the rest one solution which uses in every thread its own
datatables completely separated as well in the database as in the datasets
(it are 2 lines, but if it where hundred it was the same in my idea)

Then there is a horizontal event necessary, and that is weird, in this
situation, there is no need for line 1 to see activity on line 2 and visa
versa (think that it would be 100lines).

The main program can be used to keep track on the activities time by time by information given to it from the threads. (Not told that it should, this is just guessing).

For that is a timer very good usable in my idea.

And I do not think that Peter's sollution are that bad, he is given them
mostly on not answered threads and therefore he has probably to guess a lot.
Guesses a lot? I'm going to use that one next time a company asks me why
something doesn't work. I'm just going to say "Yeah, I guessed on how it
should work... sorry it cost you so much money... but such is life."
Cor

Nov 20 '05 #8

P: n/a
Cor
Hi CJ,

I think it is not an horizontaly approach and that is the problem.
I think the current solution should be seen as something like this.

Sub main
- thread B (which uses a timer to control)
- thread A.

While it should be in my opinion
Sub main (Which uses a system.threading.timer to do checking time by time,
or a better method if it is needed that if it has to be in real time)
- thread A
- thread B
- thread Xn.

Than could all the threads be from the same class.

But as I said, the problem is not really clear for me.

But again just my thought.

And what about Peter, your message did look to me a little bit if he did
everything wrong.
But I think that makes mistakes like you and me ("lessons") but not that
much as I got the idea from your message.

:-))

Cor

Nov 20 '05 #9

P: n/a
Cor
Hi CJ,

I did not know how to write this, now I know, I was mixing you up with
someone totally different sometimes active in this newsgroup.

Stuppid me, I would have written it in a different way normaly to you.

(much less lines)

But mistakes are lessons

:-))

Cor

Nov 20 '05 #10

P: n/a
Hehe, I have to ask, why much less lines?

Am I the black sheep of the newsgroup?
"Cor" <no*@non.com> wrote in message
news:OH****************@TK2MSFTNGP11.phx.gbl...
Hi CJ,

I did not know how to write this, now I know, I was mixing you up with
someone totally different sometimes active in this newsgroup.

Stuppid me, I would have written it in a different way normaly to you.

(much less lines)

But mistakes are lessons

:-))

Cor

Nov 20 '05 #11

P: n/a
Hi CJ,

I reviewed the replies that you posted here. My understanding is that you
are suggesting using a EventHandler to handle an event fired from another
thread. If I miss something here, or if I misunderstood any thing, please
correct me.

As far as I know, the EventHandler delegate doesn't mashal a call from a
thread to another. Therefore if you raise a event from thread A, the event
handler will be executed in thread B regardless in which thread that object
is created.

Bob, I saw that Peter suggested to use synchronization objects. I believe
this is viable. Basically you have to check the status of the
synchronization objects in thread A, and change the status of the
synchronization objects from thread B. When thread A founds status of the
synchronization object changes, it does what ever it needs.

CJ's posts do remind me of another approach to the problem. Usually we can
use MethodInvoker delegate on Windows Controls to make cross thread call.
And the code snippet shows how:

Public Class DataForm1
Inherits System.Windows.Forms.Form

Private frm As DataForm1

'Code Omitted

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim t1 As Thread = New Thread(New ThreadStart(AddressOf
ThreadProc1))
Dim t2 As Thread = New Thread(New ThreadStart(AddressOf
ThreadProc2))

t1.Start()
t2.Start()

t1.Join()
t2.Join()
End Sub

Public Sub Thread2NotifyThread1()
Debug.WriteLine("Thread2NotifyThread1, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
End Sub

<STAThread()> _
Protected Sub ThreadProc1()
Debug.WriteLine("ThreadProc1, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
frm = New DataForm1

Dim sMsg As String = "frm.Handle: " & frm.Handle.ToString()
Debug.WriteLine(sMsg)
Dim i As Integer
For i = 0 To 1000
'Do your work here.
Thread.Sleep(10)
Application.DoEvents()
Next
End Sub
<STAThread()> _
Protected Sub ThreadProc2()
Debug.WriteLine("ThreadProc2, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
Thread.Sleep(500) 'Wait till Thread 1 creates Frm
frm.Invoke(New MethodInvoker(AddressOf frm.Thread2NotifyThread1))
End Sub

Thread 1 creates a Form1 object frm, and do its work in a loop. In the loop
it calls Application.DoEvents() so that the frm's method can be called by
Thread 2. In the thread 2, it uses MethodInvoker to execute method on the
frm object.

This approach is not intuitive as using synchronization objects. Anyway it
does looks simpler and easier to code.

Best regards,
David Yuan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #12

P: n/a
David,
Hi CJ,

I reviewed the replies that you posted here. My understanding is that you
are suggesting using a EventHandler to handle an event fired from another
thread. If I miss something here, or if I misunderstood any thing, please
correct me.

I was using eventhandler delegate as an example. Not necessarily saying to
use that one in particular but the idea of delegates in general. As I
understood it (and I could be wrong, but would like clarification if so) was
that a delegate would marshal the call across threads.

Now, my reasoning, which is very important. Take for example you have a
status window with a textbox ( or anything inheriting
system.windows.forms.control). Now you start X # of threads... So you
invoke a method on ClassA... ClassA has an event called myStatusEvent as
myStatusEventHandler. It has one property, thats message( for
simplicity)... so we have.

Public Class ClassA

Public Event myStatusEvent as myStatusEventHandler

private _otherClass as ClassA 'used for referencing other thread object

public property OtherClass as ClassA
Get
return _otherClass
End get
set (value as ClassA)
_otherClass = value
Addhandler _otherClass.myStatusEvent, new MyStatusEventHandler _
(AddressOf onStatusEvent)
end set
end property
Public Sub Execute()

...... do your stuff...

RaiseEvent myStatusEvent(me, new StatusEventArgs("Thread Raised
Event..."))

End Sub

private sub onStatusEvent (sender as object, e as StatusEventArgs)
... (delegate should marshal event from other thread??? because its
raised within execute??) This is where I think I may be
confused.
end sub

As far as I know, the EventHandler delegate doesn't mashal a call from a
thread to another. Therefore if you raise a event from thread A, the event
handler will be executed in thread B regardless in which thread that object is created.

Bob, I saw that Peter suggested to use synchronization objects. I believe
this is viable. Basically you have to check the status of the
synchronization objects in thread A, and change the status of the
synchronization objects from thread B. When thread A founds status of the
synchronization object changes, it does what ever it needs.

CJ's posts do remind me of another approach to the problem. Usually we can
use MethodInvoker delegate on Windows Controls to make cross thread call.
I think this is where I was going with it... The reason being, I remember
coming across a similar problem when doing the status events and needing to
do a cross thread call to write to the owning thread... (the thread that
owns the control).
But nonetheless... A delgate is a delegate... So should it matter if the
delegate is a MethodInvoker Delegate??? Is there something I'm missing?
Because what your writing is just another way of putting my reasoning as I
see it.

and in no way is this meant to be bad. But like most people here I want to
be a better programmer, so if I'm doing something wrong, I want to know.

And my harshness towards Peter? I just can't get over the incessent "Thanks
for posting to the community" (I know I'm not the only one) and constantly
restating the question. I just expect someone from the dcompany that
developed the product to provide a better solution than a 14 year old.

That and I hate timers... especially for synchronization (I'm on a project
right now that I'm re-writing in which case they did asynchronous calls with
a timer... and no syncronization on the variable... it was a financial
trading application.. so imagine my paranoia.. =))
And the code snippet shows how:

Public Class DataForm1
Inherits System.Windows.Forms.Form

Private frm As DataForm1

'Code Omitted

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim t1 As Thread = New Thread(New ThreadStart(AddressOf
ThreadProc1))
Dim t2 As Thread = New Thread(New ThreadStart(AddressOf
ThreadProc2))

t1.Start()
t2.Start()

t1.Join()
t2.Join()
End Sub

Public Sub Thread2NotifyThread1()
Debug.WriteLine("Thread2NotifyThread1, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
End Sub

<STAThread()> _
Protected Sub ThreadProc1()
Debug.WriteLine("ThreadProc1, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
frm = New DataForm1

Dim sMsg As String = "frm.Handle: " & frm.Handle.ToString()
Debug.WriteLine(sMsg)
Dim i As Integer
For i = 0 To 1000
'Do your work here.
Thread.Sleep(10)
Application.DoEvents()
Next
End Sub
<STAThread()> _
Protected Sub ThreadProc2()
Debug.WriteLine("ThreadProc2, Thread id: " +
Thread.CurrentThread.GetHashCode().ToString())
Thread.Sleep(500) 'Wait till Thread 1 creates Frm
frm.Invoke(New MethodInvoker(AddressOf frm.Thread2NotifyThread1))
End Sub

Thread 1 creates a Form1 object frm, and do its work in a loop. In the loop it calls Application.DoEvents() so that the frm's method can be called by
Thread 2. In the thread 2, it uses MethodInvoker to execute method on the
frm object.

This approach is not intuitive as using synchronization objects. Anyway it
does looks simpler and easier to code.

Best regards,
David Yuan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #13

P: n/a
Using VS 2003, Vb, MSDE...

Every now and then you open a hornet's nest. Thanks for all the replies,
they have been very helpful, although many of the responses harshly disagree
with each other. We all want to be better programmers.

These are my results of Using RaiseEvents vs Using A System.Timers.Timer.

Using RaiseEvents - You can indeed create a horizontal RaiseEvent that is
caught by an event handler in an unrelated parellel thread. Since I only
wanted certain threads to catch the event, after all threads were created, I
used code like below to put the add handler the the specific thread where it
was needed. All threads are added to gsArray_of_Trunk_Threads as they are
created. The Event Shutdown_Trunk_Thread_Non_Gracefully just means you
hang up on any caller currently talking on that trunk. So, below puts the
add handler in thread 1 only.

AddHandler Me.Shutdown_Trunk_Thread_Non_Gracefully, AddressOf
gsArray_of_Trunk_Threads(1).Shutdown_Trunk_Thread_ Non_Gracefully_EventHandle
r

I also tried different ways of doing the above, all with the same results
below.

When raised by thread 0, the event is caught by thread 1. However, I have
discovered that 1) the delagate
Shutdown_Trunk_Thread_Non_Gracefully_EventHandler is running under thread 0
based on the debug threading window and 2) the delagate method is totally
unaware of any of thread 1 instantiations (particcularly Com Object
instantiations) in the Declarations section. All of these trunk threads are
running in ApartmentState.STA, which is a requirement of Intel's Dialogic
cards. So, if I call the Dialogic card command to go on hook to hang up, it
fails, essentially saying no trunk was ever assigned, which of course isn't
true, since someone is talking on that trunk right now.

Is this what you would expect?

Using A System.Timers.Timer- If you do the same thing via a timer on thread
1 (i.e. execute Shutdown_Trunk_Thread_Non_Gracefully_EventHandler or
equivalent), the timer is 1) running under a seperate thread based on the de
bug threading window (like the RaiseEvent in option above), but 2) it DOES
seem to
be aware of all instantiations of that thread 1 in its declarations section
and works fine.

Is this what you would expect?

Anyway, it looks like timer is the way to go in my case.

I look forward to your replies and appreciate them all.

Thanks!
Bob

Nov 20 '05 #14

P: n/a
Hey bob,

Glad you found a solution the way you wanted.. However, (and thats
completly fine), your addhandler method never uses a delegate...which is why
you may still be in the same thread.. Address of simple creates a function
pointer, doesn't delegate across.

but hey, timers work, then timers work, and thats all thats important isn't
it? =)

Good luck,
CJ

"Bob Day" <Bo****@TouchTalk.net> wrote in message
news:uA****************@TK2MSFTNGP12.phx.gbl...
Using VS 2003, Vb, MSDE...

Every now and then you open a hornet's nest. Thanks for all the replies,
they have been very helpful, although many of the responses harshly disagree with each other. We all want to be better programmers.

These are my results of Using RaiseEvents vs Using A System.Timers.Timer.

Using RaiseEvents - You can indeed create a horizontal RaiseEvent that is
caught by an event handler in an unrelated parellel thread. Since I only
wanted certain threads to catch the event, after all threads were created, I used code like below to put the add handler the the specific thread where it was needed. All threads are added to gsArray_of_Trunk_Threads as they are
created. The Event Shutdown_Trunk_Thread_Non_Gracefully just means you
hang up on any caller currently talking on that trunk. So, below puts the
add handler in thread 1 only.

AddHandler Me.Shutdown_Trunk_Thread_Non_Gracefully, AddressOf
gsArray_of_Trunk_Threads(1).Shutdown_Trunk_Thread_ Non_Gracefully_EventHandle r

I also tried different ways of doing the above, all with the same results
below.

When raised by thread 0, the event is caught by thread 1. However, I have
discovered that 1) the delagate
Shutdown_Trunk_Thread_Non_Gracefully_EventHandler is running under thread 0 based on the debug threading window and 2) the delagate method is totally
unaware of any of thread 1 instantiations (particcularly Com Object
instantiations) in the Declarations section. All of these trunk threads are running in ApartmentState.STA, which is a requirement of Intel's Dialogic
cards. So, if I call the Dialogic card command to go on hook to hang up, it fails, essentially saying no trunk was ever assigned, which of course isn't true, since someone is talking on that trunk right now.

Is this what you would expect?

Using A System.Timers.Timer- If you do the same thing via a timer on thread 1 (i.e. execute Shutdown_Trunk_Thread_Non_Gracefully_EventHandler or
equivalent), the timer is 1) running under a seperate thread based on the de bug threading window (like the RaiseEvent in option above), but 2) it DOES
seem to
be aware of all instantiations of that thread 1 in its declarations section and works fine.

Is this what you would expect?

Anyway, it looks like timer is the way to go in my case.

I look forward to your replies and appreciate them all.

Thanks!
Bob

Nov 20 '05 #15

P: n/a
CJ,

I am afraid that delegate is not that magic that it can do the cross-thread
notification stuff for you. ;). I demonstrated how to use the MethodInvoker
delegate in my last post. But magic thing doesn't happen within it. In fact
the cross-thread plumbing work is done by the Control.Invoke method. Note
that in the ThreadProc2, I called frm.Invoke, this method marshals the call
to the thread 1. You can have a look at the MSDN or the link below for more
information:

http://msdn.microsoft.com/library/de...us/cpref/html/
frlrfSystemWindowsFormsControlClassInvokeTopic.asp

I totally understand your concern about the cross-thread programming.
Inappropriate usage of it can cause a degrade of the application's
performance, if you are lucky, or a disasterous crash, if you are not. :)

Bob, I understand that you are using a Timer to poll the changes made by
another thread. I believe that the cost of this approach depends on how
much work you need to perform in each poll. If it is easy to check changes
made by another thread each time the Timer fires, this approach should work
fine. However if it is not, you may want to consider using the
synchronization objects. The code snippet below demonstrats how to use a
AutoResetEvent object to notify another thread:

Imports System.Threading

Module Module1
Dim AutoEvent As AutoResetEvent
Dim ThreadExitEvent As AutoResetEvent

Public Sub ThreadProc()
Dim workingThreadCondition As Integer
For workingThreadCondition = 1 To 5
'You may add your working stuff in the loop
Thread.Sleep(1000)
AutoEvent.Set()
Next

'Singal the main thread that I am exiting
ThreadExitEvent.Set()
Debug.WriteLine("Worker Threading Exits")
End Sub

Sub Main()
AutoEvent = New AutoResetEvent(False)
ThreadExitEvent = New AutoResetEvent(False)

Dim workingThread As New Thread(AddressOf ThreadProc)
workingThread.Start()

'We check if the worker thread has exited.
While Not ThreadExitEvent.WaitOne(0, False)
'You may add your working stuff in the loop
'Check if the worker thread has notifications here
If AutoEvent.WaitOne(0, False) Then
Debug.WriteLine("woker thread signal fired")
End If
Thread.Sleep(1000)
End While
'Wait for working thread exit
workingThread.Join()
Debug.WriteLine("Main Threading Exits")
End Sub
End Module

Best regards,
David Yuan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #16

P: n/a
Cor
Hi David,

I really do not understand why my messages in this thread are totally
ignored.

I give my opinion that managing threads horizontaly is a not good approach.
In some lines you admit that but I get more and more the idea that you are
trying to make the example from Peter is the right one.

I do not say the example from Peter is wrong (I did not check it, so I
cannot say that), I say the approach is wrong. (Peter did try to give his
best answer to the direct question).

And therefore I think this is not a good advice.

But just my thought about it.

(If you disagree with me and say managing threads horizontally is the best
approach, than I am curious to your answer).

Cor


Nov 20 '05 #17

P: n/a
David,
CJ,

I am afraid that delegate is not that magic that it can do the cross-thread notification stuff for you. ;). I demonstrated how to use the MethodInvoker delegate in my last post. But magic thing doesn't happen within it. In fact the cross-thread plumbing work is done by the Control.Invoke method. Note
that in the ThreadProc2, I called frm.Invoke, this method marshals the call to the thread 1. You can have a look at the MSDN or the link below for more information:

Ok, thats what I was thinking of. I was misunderstanding the use of a
delegate (sort of). I understand its nothing more than a glorified function
pointer, but I didn't know if it helped marshal the call. I thought I read
a blog (which was probably a mistake taking it as verbatim...) that said
this was true. I don't know, I do a lot of reading in a day. =)

however, the control.invoke was the approach I was trying to communicate. I
remember building an app before that I would throw an exception (can't
remember which one) if I was running a multi-threaded process and notifying
a single control (multi-line text box) of changes within the threads using
events. Because the threads were different, I used a delegate to use
control.invoke. I was just mixed up on what did what and when. =)

So sorry for the confusion. Just want to make sure I get it right.
http://msdn.microsoft.com/library/de...us/cpref/html/ frlrfSystemWindowsFormsControlClassInvokeTopic.asp

I totally understand your concern about the cross-thread programming.
Inappropriate usage of it can cause a degrade of the application's
performance, if you are lucky, or a disasterous crash, if you are not. :)

Yes... as many of us have learned by example. =) I just have experience
with timers being incredibly expensive, and after a recent project, in which
case a timer was used for synchronization (if you want to call it that...)
I have a bit of a bad taste for them.

Thanks for your efforts and it is appreciated greatly...
Bob, I understand that you are using a Timer to poll the changes made by
another thread. I believe that the cost of this approach depends on how
much work you need to perform in each poll. If it is easy to check changes
made by another thread each time the Timer fires, this approach should work fine. However if it is not, you may want to consider using the
synchronization objects. The code snippet below demonstrats how to use a
AutoResetEvent object to notify another thread:

Imports System.Threading

Module Module1
Dim AutoEvent As AutoResetEvent
Dim ThreadExitEvent As AutoResetEvent

Public Sub ThreadProc()
Dim workingThreadCondition As Integer
For workingThreadCondition = 1 To 5
'You may add your working stuff in the loop
Thread.Sleep(1000)
AutoEvent.Set()
Next

'Singal the main thread that I am exiting
ThreadExitEvent.Set()
Debug.WriteLine("Worker Threading Exits")
End Sub

Sub Main()
AutoEvent = New AutoResetEvent(False)
ThreadExitEvent = New AutoResetEvent(False)

Dim workingThread As New Thread(AddressOf ThreadProc)
workingThread.Start()

'We check if the worker thread has exited.
While Not ThreadExitEvent.WaitOne(0, False)
'You may add your working stuff in the loop
'Check if the worker thread has notifications here
If AutoEvent.WaitOne(0, False) Then
Debug.WriteLine("woker thread signal fired")
End If
Thread.Sleep(1000)
End While
'Wait for working thread exit
workingThread.Join()
Debug.WriteLine("Main Threading Exits")
End Sub
End Module

Best regards,
David Yuan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #18

P: n/a
Thanks for all the info - it was very helpful.
Bob Day

"Bob Day" <Bo****@TouchTalk.net> wrote in message
news:ub****************@TK2MSFTNGP12.phx.gbl...
Using VS 2003, VB, MSDE...

There are two threads, A & B, that continously run and are started by Sub
Main. They instantiationsl of identical code. Thread A handles call
activity on telephone line 1 and Thread B handles call activity on telephone line 2. They use a common SQL datasource, but all DataSets are unique to
each thread.

Is there a way for thread A to occasionally communication to thread B that
something has happened? The ideal situation would be for thread A to raise an event that a handler in thread B handles. But, I don't see how to do
that (the raised event would be handled "up the call stack" in Sub Main, not "horizontially" by the other thread).

Specifically, thread A has added a row(s) to the common datasource that I
need thread B to know about. I am currently doing it with a timer in thread B that check the common datasource for changes every 15 seconds, which works OK, but am looking for a simpler solution. I have looked at SQL triggers, but don't see how that would alert thread B. I have looked at RaseEvents,
but don't see any help there either.

Any ideas? Do System.Timers. exert a heavy resource usage toll? If not I
may jus stick with the timer method.

Thansk!

Bob

Nov 20 '05 #19

P: n/a
Hi Cor,

I am sorry I didn't reply to you, this is because I am not sure what do you
mean by "horizontal threads" exactly. :)

I did see that in some previous posts that you suggest to use separate data
store for each of the threads. But I am afraid this is not practical in
Bob's programming scenario. It is ideal that every thread has its own
resouces such as data store. However the reality is sometimes you have to
share resouces among threads.

And if we do have to, there are cateories of approaches. The first one is
to to poll the resource constantly, which includes the timer approach. The
other category is to use synchronization objects such as AutoResetEvent to
send notifications between threads.

The Control.Invoke method that I demonstrated is in fact a variant of using
synchronization objects. It is in fact using the windoes message queue for
synchronization.

Best regards,
David Yuan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #20

P: n/a
Cor
Hi David,

Thanks for your answer,

What I did try to show in this thread is (the problem is not important
anymore) that there is chosen for a thread solution instead of a remoting
solution. There is a Main process, which starts two threads.

With "horizontal" solutions, I mean that the managing of the solution is not
ordered by a higher vertical level but done on the same process level.

However, it is worse, the solution is:
Main
- B
- A
B is doing the control part using timers, (I said before those timers is not
the most important of the bad design).

The solution could have been remoting (and than I agree, with all what you
say)
A B with control to each other

Or multithreading
Main (with control over A and B)
A B

What you said about what I should have said about the data process approach
I never said, in both situations it is in my opinion that the best (the
only) choose to use separated data, it would otherwise kill it self in
concurrency problems.

I hope this makes it clearer.

Cor


Nov 20 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.