473,395 Members | 1,473 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Waiting on a Thread - Revisited

Hi guys. I'm back on the threading gig again.

It's the age-old question about waiting for something to happen without
wasting time doing it.

Take two threads: the main thread and a worker thread. The worker thread is
reading the serial port, waiting for something to happen (a service
request). When it does it raises an event. Of course, the event is executed
on the worker thread. The idea is that when the event is raised, the handler
issues a command on the serial port and waits for a response. The problem is
that the part of the worker thread that does the listening (for replies) is
tied up with the event it has just raised, and therefore cannot listen for
the latest reply.

So, I think that when the event is raised, I need to set a flag perhaps,
that can be picked up on the main thread. This way the event completes, the
worker thread goes back to listening for replies, and the main thread sees
the flag and issues its command.

Sounds good, but now I have to periodically check for the flag in the main
thread. That sounds an awful lot like polling to me, and I don't want to
waste time polling.

How can I catch the flag in the main thread when it changes, without having
to sit and wait for it?

As usual, any suggestions about how else to do this are always welcome,
however radical.

TIA

Charles
Jul 21 '05 #1
44 2307
Hi Charles,

When I see your problem my answer is direct remoting, however maybe this can
also done by a threading program. It is a problem old as hell. There is in
my opinion needed a stack.

So why not create a stack using an arraylist.

You start your sub tread every time something is done from the first row of
that arraylist (when the tread is not active you can polling the arraylist
using the thread.threading.sleep if there is something) and delete that
item it is done.

While you add every time to the last row when there is something to be done,
this simple solution would work in my opinion

Cor
Jul 21 '05 #2
Charles Law <bl***@nowhere.com> wrote:

<snip>
Sounds good, but now I have to periodically check for the flag in the main
thread. That sounds an awful lot like polling to me, and I don't want to
waste time polling.

How can I catch the flag in the main thread when it changes, without having
to sit and wait for it?

As usual, any suggestions about how else to do this are always welcome,
however radical.


I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #3
Hi Cor

I have just read Jon's article on multi-threading in .NET and I now
understand how the Wait and Pulse methods work, so I am going to try that.
It looks like just the job.

Thanks for your suggestion though, as I think it is going to help me in
another area, related to the same task.

Charles
"Cor Ligthert" <no**********@planet.nl> wrote in message
news:OZ****************@TK2MSFTNGP11.phx.gbl...
Hi Charles,

When I see your problem my answer is direct remoting, however maybe this can also done by a threading program. It is a problem old as hell. There is in
my opinion needed a stack.

So why not create a stack using an arraylist.

You start your sub tread every time something is done from the first row of that arraylist (when the tread is not active you can polling the arraylist
using the thread.threading.sleep if there is something) and delete that
item it is done.

While you add every time to the last row when there is something to be done, this simple solution would work in my opinion

Cor

Jul 21 '05 #4
Hi Jon

I have just read your article and the mud has cleared (a little). I have
created another thread to respond to service requests, so as not to hold up
my main thread, and used the Wait and Pulse methods to signal between the
worker thread and the new thread. Just a few refinements to make and it'll
be there ... ;-)

Cheers.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:

<snip>
Sounds good, but now I have to periodically check for the flag in the main thread. That sounds an awful lot like polling to me, and I don't want to
waste time polling.

How can I catch the flag in the main thread when it changes, without having to sit and wait for it?

As usual, any suggestions about how else to do this are always welcome,
however radical.


I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #5
Hi Jon

I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up
:-)

However, I am noticing some odd behaviour. My previous solution used a do
loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change
state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time
to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for service
requests from the comms thread. The comms thread call Monitor.Pulse(myflag)
whilst the service request thread call Monitor.Wait. On that basis, I would
expect the UI thread to be unhindered, but that does not seem to be the
case.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:

<snip>
Sounds good, but now I have to periodically check for the flag in the main thread. That sounds an awful lot like polling to me, and I don't want to
waste time polling.

How can I catch the flag in the main thread when it changes, without having to sit and wait for it?

As usual, any suggestions about how else to do this are always welcome,
however radical.


I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #6
Hi, Charles

if you use Wait on UI thread - that's the reason. Wait passes effectively
control out of calling thread, so it's even worse than DoEvents in this
respect. If you use lock on UI thread on same object(s), which are used in
Monitor.Wait - that's one additional reason.

I lost track of original questions/answers, so can recommend only - remove
Wait from UI thread and check what and where you lock. Attach event to
thread object, assign UI thread delegate to event when constructing thread
and use Pulse in UI thread and Wait in worker thread. Minimize time spent in
lock sections.

Take a look at examples at
http://msdn.microsoft.com/msdnmag/is...Multithreading and in MSDN
also, if you haven't seen them yet.

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi Jon

I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up
:-)

However, I am noticing some odd behaviour. My previous solution used a do
loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change
state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for service requests from the comms thread. The comms thread call Monitor.Pulse(myflag) whilst the service request thread call Monitor.Wait. On that basis, I would expect the UI thread to be unhindered, but that does not seem to be the
case.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:

<snip>
Sounds good, but now I have to periodically check for the flag in the main thread. That sounds an awful lot like polling to me, and I don't want to waste time polling.

How can I catch the flag in the main thread when it changes, without having to sit and wait for it?

As usual, any suggestions about how else to do this are always welcome, however radical.


I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Jul 21 '05 #7
Charles Law <bl***@nowhere.com> wrote:
I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up
:-)

However, I am noticing some odd behaviour. My previous solution used a do
loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change
state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time
to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for service
requests from the comms thread. The comms thread call Monitor.Pulse(myflag)
whilst the service request thread call Monitor.Wait. On that basis, I would
expect the UI thread to be unhindered, but that does not seem to be the
case.


I'm not sure what you're doing in your UI thread - I would strongly
suggest not having a Monitor.Wait in your UI thread at all, nor having
calls to Application.DoEvents(). The UI thread should solely be for UI
actions.

What are you doing on the UI thread other than short-running UI
operations?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #8
Hi Alex

What I was trying to say was that there is no Wait in my UI thread. That is
why I am surprised by the effect. The threads that use monitor are the comms
thread and the service request thread.

Charles
"AlexS" <sa***********@SPAMsympaticoPLEASE.ca> wrote in message
news:OZ*************@TK2MSFTNGP10.phx.gbl...
Hi, Charles

if you use Wait on UI thread - that's the reason. Wait passes effectively
control out of calling thread, so it's even worse than DoEvents in this
respect. If you use lock on UI thread on same object(s), which are used in
Monitor.Wait - that's one additional reason.

I lost track of original questions/answers, so can recommend only - remove
Wait from UI thread and check what and where you lock. Attach event to
thread object, assign UI thread delegate to event when constructing thread
and use Pulse in UI thread and Wait in worker thread. Minimize time spent in lock sections.

Take a look at examples at
http://msdn.microsoft.com/msdnmag/is...Multithreading and in MSDN
also, if you haven't seen them yet.

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi Jon

I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up
:-)

However, I am noticing some odd behaviour. My previous solution used a do loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time
to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for

service
requests from the comms thread. The comms thread call

Monitor.Pulse(myflag)
whilst the service request thread call Monitor.Wait. On that basis, I

would
expect the UI thread to be unhindered, but that does not seem to be the
case.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:

<snip>

> Sounds good, but now I have to periodically check for the flag in
the main
> thread. That sounds an awful lot like polling to me, and I don't

want to > waste time polling.
>
> How can I catch the flag in the main thread when it changes, without

having
> to sit and wait for it?
>
> As usual, any suggestions about how else to do this are always welcome, > however radical.

I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too



Jul 21 '05 #9
Hi Jon

I was halfway through a response about not having a wait in my UI thread
when it dawned on me what I am doing. I will have to rethink this.

Thanks.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:
I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up :-)

However, I am noticing some odd behaviour. My previous solution used a do loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for service requests from the comms thread. The comms thread call Monitor.Pulse(myflag) whilst the service request thread call Monitor.Wait. On that basis, I would expect the UI thread to be unhindered, but that does not seem to be the
case.


I'm not sure what you're doing in your UI thread - I would strongly
suggest not having a Monitor.Wait in your UI thread at all, nor having
calls to Application.DoEvents(). The UI thread should solely be for UI
actions.

What are you doing on the UI thread other than short-running UI
operations?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #10
Alex

A correction. I have just realised that I have fallen victim of my own
attempt to oversimplify the problem. I am indeed using wait in my UI thread,
which is not what I had intended. The words drawing, board and back spring
to mind ;-)

Charles
"AlexS" <sa***********@SPAMsympaticoPLEASE.ca> wrote in message
news:OZ*************@TK2MSFTNGP10.phx.gbl...
Hi, Charles

if you use Wait on UI thread - that's the reason. Wait passes effectively
control out of calling thread, so it's even worse than DoEvents in this
respect. If you use lock on UI thread on same object(s), which are used in
Monitor.Wait - that's one additional reason.

I lost track of original questions/answers, so can recommend only - remove
Wait from UI thread and check what and where you lock. Attach event to
thread object, assign UI thread delegate to event when constructing thread
and use Pulse in UI thread and Wait in worker thread. Minimize time spent in lock sections.

Take a look at examples at
http://msdn.microsoft.com/msdnmag/is...Multithreading and in MSDN
also, if you haven't seen them yet.

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Hi Jon

I have implemented a solution using SyncLock, Wait and Pulse, and all is
well. My CPU time has gone down from 30% to nil, which always cheers me up
:-)

However, I am noticing some odd behaviour. My previous solution used a do loop, with DoEvents in it and a test for my flag, whereas the current
solution calls

Monitor.Wait(myflag, 100)

to wait for 100ms before returning.

Using DoEvents, I could click on a checkbox on-screen and it would change state with each click. Now, using Monitor.Wait, I have to click the box
several time before it changes state. It's as if the UI is not getting time
to service the clicks.

Is that behaviour you would expect using Monitor.Wait?

At this point I have three threads running: the main UI thread, a comms
thread that listens to the serial port, and a thread that waits for

service
requests from the comms thread. The comms thread call

Monitor.Pulse(myflag)
whilst the service request thread call Monitor.Wait. On that basis, I

would
expect the UI thread to be unhindered, but that does not seem to be the
case.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:

<snip>

> Sounds good, but now I have to periodically check for the flag in
the main
> thread. That sounds an awful lot like polling to me, and I don't

want to > waste time polling.
>
> How can I catch the flag in the main thread when it changes, without

having
> to sit and wait for it?
>
> As usual, any suggestions about how else to do this are always welcome, > however radical.

I'm afraid I didn't follow your example very closely, but it sounds
like you basically want Monitor.Wait and Monitor.Pulse.

I've got an unfinished article which talks about them (and other
things) - it's at
http://www.pobox.com/~skeet/csharp/multithreading.html

There's more to come when I get round to it, but the bit in "More
Monitor methods" described Wait and Pulse.

(You could also use ManualResetEvent or AutoResetEvent.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too



Jul 21 '05 #11
Charles Law <bl***@nowhere.com> wrote:
What I was trying to say was that there is no Wait in my UI thread. That is
why I am surprised by the effect. The threads that use monitor are the comms
thread and the service request thread.


So what is the UI thread doing, do you know? It might be worth breaking
into the app in debug mode while it's being unresponsive, and see if
you can see where the UI thread is.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #12
Charles Law <bl***@nowhere.com> wrote:
A correction. I have just realised that I have fallen victim of my own
attempt to oversimplify the problem. I am indeed using wait in my UI thread,
which is not what I had intended. The words drawing, board and back spring
to mind ;-)


:)

Don't worry about it - threading is a tough nut to crack, and you
*always* have to be wary. (I squashed a deadlock bug today and felt
rather victorious - until I started wondering whether we've got any
others.)

If we can help any more, just ask - it often helps just to post your
potential plan of action, as then you tend to spot the flaws (if any!)
about 10 seconds after posting it. At least, that's my experience...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #13
Hi Jon

I have been confusing two different bits of kit attached to the serial
ports. One is a long standing item that has a complicated path between UI
and comms. The other, which I added a couple of days ago, has a more direct
connection, and uses an ASCII protocol. The latter is the one that raises
service requests, and seems to be working fine. Having added it
successfully, I returned to the original item and thought I would 'improve'
it's operation by using SyncLock and Monitor.Wait/Pulse. What I failed to
appreciate was that the old kit was communicating straight off the UI
thread, so when I changed to using Monitor.Wait instead of a timeout loop
with DoEvents, the UI suddenly started behaving badly.

....

Actually, now I think about it, I was right the first time: my UI thread
does _not_ use Wait. I have a polling thread as well (you must think I don't
know what I am doing). The polling thread sends commands to the original
item and waits for a reply. It waits using Monitor.Wait and the comms thread
pulses to alert the polling thread when a reply has been received.
Therefore, my UI thread is just sitting in the normal message loop, waiting
for the user to click something.

When I use the timeout loop with DoEvents in the polling thread, the UI is
responsive. When I use Monitor.Wait in the polling thread, the UI starts to
play up, taking several clicks to change a checkbox state. [I should add at
this point that with each click of the checkbox, a command is sent to the
serial port and on to the external hardware. The polling thread retrieves
status information, one bit of which indicates whether the checkbox should
be checked or not. I have to click several times before the hardware sends a
status message showing that it received the command].

What is odd is that the it works smoothly when I use the timeout loop with
DoEvents, but not when I use Monitor.Wait.

I think I am going to have to draw a picture of what is happening - this is
doing my head in.

Charles
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Charles Law <bl***@nowhere.com> wrote:
What I was trying to say was that there is no Wait in my UI thread. That is why I am surprised by the effect. The threads that use monitor are the comms thread and the service request thread.


So what is the UI thread doing, do you know? It might be worth breaking
into the app in debug mode while it's being unresponsive, and see if
you can see where the UI thread is.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #14
Hi Charles,

And comes my solution again in picture?

I have thought your problem over as well, now I know I do it like that I
told, however I use the listview as the stack container.

And it works very fine.

Cor
Jul 21 '05 #15
Hi Cor

I am going to look at that again too. The idea of a stack, or queue seems a
good one. I will need some way of queuing replies as well, and tagging them
to the outgoing message, but then I think it will be very neat.

Charles
Cor Ligthert wrote:
Hi Charles,

And comes my solution again in picture?

I have thought your problem over as well, now I know I do it like
that I told, however I use the listview as the stack container.

And it works very fine.

Cor

Jul 21 '05 #16
Charles Law <bl***@nowhere.com> wrote:
I am going to look at that again too. The idea of a stack, or queue seems a
good one. I will need some way of queuing replies as well, and tagging them
to the outgoing message, but then I think it will be very neat.


A queue is likely to be more useful to you than a stack, unless you
*really* want to process things in a strange order :)

The page I pointed you at before
(http://www.pobox.com/~skeet/csharp/multithreading.html) happens to
provide an example of a producer/consumer system based on a queue - it
may well be useful to you.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #17
Hi Jon

I think you are right. I slept on it and it is taking shape in my mind. I
already have a class that constructs messages and deecodes replies, and it
seems the obvious place to add a new method, that can be executed as a new
thread, to monitor a queue and despatch messages. My main thread can then
post a message, pulse the queue, and then go back to what it was doing.

I'll post back when I have it working ... I could be gone some time ;-)

Charles
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I am going to look at that again too. The idea of a stack, or queue
seems a good one. I will need some way of queuing replies as well,
and tagging them to the outgoing message, but then I think it will
be very neat.


A queue is likely to be more useful to you than a stack, unless you
*really* want to process things in a strange order :)

The page I pointed you at before
(http://www.pobox.com/~skeet/csharp/multithreading.html) happens to
provide an example of a producer/consumer system based on a queue - it
may well be useful to you.

Jul 21 '05 #18
Hi Charles,

You are right the word is queue, however for me a stack is a first In first
Out queue and I am using for a First In First Out queue as well the word
stack, however queue should be the word. (Queue is a difficult word for me
to write maybe because it looks so much on the French "What")

However, for you as an Englishman queue means more, I once was early in
London very early on the station, and there where all people waiting nice in
a queue. Than there came some people who went to the front of the queue, I
said to my friend "probably Dutchman", and I was right. Therefore, you see
it has here a different meaning.

:-)))

For who does not know this I am a Dutchman.

Cor
Jul 21 '05 #19
Hi Cor

We are very attached to our queues, and all they do is upset us - we spend
all our time worrying about whether someone else is pushing in, and looking
round franticly to make sure there isn't.

There is a British comedienne - Victoria Wood - who describes a situation
where a young couple on a train start kissing. The other people in the
carriage smile indulgently. Then the couple become more amorous, and the
other people in the carriage become more uncomfortable; but they say
nothing. The couple begin to remove each other's clothing, but still the
other passengers say nothing. Then, the couple start to make love, and the
other passengers just put their heads down and become ever more engrossed in
their reading matter.

Finally, when the couple have finished, the young man sits back and lights
up a cigarette, with which a woman calls over indignantly "I think you'll
find this is a non-smoking carriage".

Only on a British train, eh?

Charles
Cor Ligthert wrote:
Hi Charles,

You are right the word is queue, however for me a stack is a first In
first Out queue and I am using for a First In First Out queue as well
the word stack, however queue should be the word. (Queue is a
difficult word for me to write maybe because it looks so much on the
French "What")

However, for you as an Englishman queue means more, I once was early
in London very early on the station, and there where all people
waiting nice in a queue. Than there came some people who went to the
front of the queue, I said to my friend "probably Dutchman", and I
was right. Therefore, you see it has here a different meaning.

:-)))

For who does not know this I am a Dutchman.

Cor

Jul 21 '05 #20
>
Then, the couple start to make love, and the
other passengers just put their heads down and become ever more engrossed in their reading matter.


Yes really a difference with here, probably here somebody stends up and asks
if he can help?

Cor
Jul 21 '05 #21
Cor Ligthert <no**********@planet.nl> wrote:
You are right the word is queue, however for me a stack is a first In first
Out queue and I am using for a First In First Out queue as well the word
stack, however queue should be the word.


That's something to watch out for in future then - stacks are generally
last-in-first-out (like a stack of plates - you put a plate on the top,
and take it off the top too).

Hence System.Collections.Stack :)

I have every sympathy with those coming to computing without English as
a native language. Life's hard enough without having to do translation
the whole time! Even though I sometimes find your English hard to
understand, it's certainly a lot better than my grasp of any other
language...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #22
Ok, I'm back. Who said this was going to be easy (actually, no one, I
think).

As usual, it's not as straight forward as I am going to describe, but this
illustrates the problem.

I have two threads: the UI thread and a polling (worker) thread. The polling
thread goes round and round updating the UI with information it reads from a
serial port, based on messages it reads from a queue. Before it reads from
the queue, it gets a lock on it (SyncLock) to synchronise adding and
removing items. If the queue contains a message it is removed, the serial
port is read, the UI is updated, and the lock is released (End SyncLock).

The UI sits happily, displaying the latest information.

Because the polling thread is not the UI thread (obviously) it can't just
stuff things onto the screen. So, when it updates a textbox, for example, it
uses a delegate and calls Textbox1.Invoke. Great ... fine, so far.

Now, the user comes along (bless him), and clicks a button. This is the
signal that a message must be added to the queue. So, the UI calls a method
to add a message to the queue. Before accessing the queue, the UI thread
gets a lock on the queue, adds its message, pulses the queue, and releases
the lock. Still sounding good.

However, when the UI thread trys to get the lock (SyncLock again) it can't
get it straight away, because the polling thread has a lock, and is about to
update the UI. Therefore, the UI thread waits patiently for the lock.

The polling thread, meanwhile, goes to update the UI. It finds it is not on
the UI thread, so sets up the delegate and calls Invoke ... and is never
heard from again.

Invoke hangs because it is now trying to marshal onto the UI thread, but the
UI thread is waiting on a lock that the polling thread holds, so we have
deadlock.

Over to you Jon / Cor / anyone :-(

Charles
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I am going to look at that again too. The idea of a stack, or queue
seems a good one. I will need some way of queuing replies as well,
and tagging them to the outgoing message, but then I think it will
be very neat.


A queue is likely to be more useful to you than a stack, unless you
*really* want to process things in a strange order :)

The page I pointed you at before
(http://www.pobox.com/~skeet/csharp/multithreading.html) happens to
provide an example of a producer/consumer system based on a queue - it
may well be useful to you.

Jul 21 '05 #23
Charles Law <bl***@nowhere.com> wrote:
Ok, I'm back. Who said this was going to be easy (actually, no one, I
think).

As usual, it's not as straight forward as I am going to describe, but this
illustrates the problem.

I have two threads: the UI thread and a polling (worker) thread. The polling
thread goes round and round updating the UI with information it reads from a
serial port, based on messages it reads from a queue. Before it reads from
the queue, it gets a lock on it (SyncLock) to synchronise adding and
removing items. If the queue contains a message it is removed, the serial
port is read, the UI is updated, and the lock is released (End SyncLock).
I think I can see what is coming...
The UI sits happily, displaying the latest information.

Because the polling thread is not the UI thread (obviously) it can't just
stuff things onto the screen. So, when it updates a textbox, for example, it
uses a delegate and calls Textbox1.Invoke. Great ... fine, so far.

Now, the user comes along (bless him), and clicks a button. This is the
signal that a message must be added to the queue. So, the UI calls a method
to add a message to the queue. Before accessing the queue, the UI thread
gets a lock on the queue, adds its message, pulses the queue, and releases
the lock. Still sounding good.

However, when the UI thread trys to get the lock (SyncLock again) it can't
get it straight away, because the polling thread has a lock, and is about to
update the UI. Therefore, the UI thread waits patiently for the lock.

The polling thread, meanwhile, goes to update the UI. It finds it is not on
the UI thread, so sets up the delegate and calls Invoke ... and is never
heard from again.
Indeed.
Invoke hangs because it is now trying to marshal onto the UI thread, but the
UI thread is waiting on a lock that the polling thread holds, so we have
deadlock.

Over to you Jon / Cor / anyone :-(


Well you've done a first rate job of analysing the problem. All you
need to do now is move the call to the UI update out of the lock, and
you're home free :)

Limit yourself to only holding the lock while you absolutely have to -
for interacting with the queue. When you've read from the queue,
release the lock and *then* do whatever you need to with the object
you've just fetched, eg update the UI.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #24
Hi, Charles

Do you really need to read port and call Invoke from non-UI thread inside
lock? As I see it, you need lock only for queue. Rule of thumb is - free
objects as soon as you can. So, release it immediately after getting message
from queue.

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:eO**************@TK2MSFTNGP12.phx.gbl...
Ok, I'm back. Who said this was going to be easy (actually, no one, I
think).

As usual, it's not as straight forward as I am going to describe, but this
illustrates the problem.

I have two threads: the UI thread and a polling (worker) thread. The polling thread goes round and round updating the UI with information it reads from a serial port, based on messages it reads from a queue. Before it reads from
the queue, it gets a lock on it (SyncLock) to synchronise adding and
removing items. If the queue contains a message it is removed, the serial
port is read, the UI is updated, and the lock is released (End SyncLock).

The UI sits happily, displaying the latest information.

Because the polling thread is not the UI thread (obviously) it can't just
stuff things onto the screen. So, when it updates a textbox, for example, it uses a delegate and calls Textbox1.Invoke. Great ... fine, so far.

Now, the user comes along (bless him), and clicks a button. This is the
signal that a message must be added to the queue. So, the UI calls a method to add a message to the queue. Before accessing the queue, the UI thread
gets a lock on the queue, adds its message, pulses the queue, and releases
the lock. Still sounding good.

However, when the UI thread trys to get the lock (SyncLock again) it can't
get it straight away, because the polling thread has a lock, and is about to update the UI. Therefore, the UI thread waits patiently for the lock.

The polling thread, meanwhile, goes to update the UI. It finds it is not on the UI thread, so sets up the delegate and calls Invoke ... and is never
heard from again.

Invoke hangs because it is now trying to marshal onto the UI thread, but the UI thread is waiting on a lock that the polling thread holds, so we have
deadlock.

Over to you Jon / Cor / anyone :-(

Charles
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I am going to look at that again too. The idea of a stack, or queue
seems a good one. I will need some way of queuing replies as well,
and tagging them to the outgoing message, but then I think it will
be very neat.


A queue is likely to be more useful to you than a stack, unless you
*really* want to process things in a strange order :)

The page I pointed you at before
(http://www.pobox.com/~skeet/csharp/multithreading.html) happens to
provide an example of a producer/consumer system based on a queue - it
may well be useful to you.


Jul 21 '05 #25
Hi Jon / Alex

Hmm. I know you're right ... but ...

I deliberately kept the whole 'read message / update UI' thing inside the
SyncLock construct because it served as a way of pacing outgoing messages.

Messages have to be sent out synchronously, and the polling thread is
capable of adding messages to the queue much faster than they can be sent.
Therefore, locking the queue whilst the message was being sent seemed a
convenient way of preventing a backlog of messages from building up in the
queue. However, when the user clicks something, their request takes
precedence over the background processing, so it is legitimate to insert the
message at the head of the queue and not have to wait.

Can you think of another way round this?

Charles
[If my spelling has started to awry it is because I have started using
OE-QuoteFix, and now the spell checker always passes, regardless of spelling
mistakes.]
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
Ok, I'm back. Who said this was going to be easy (actually, no one, I
think).

As usual, it's not as straight forward as I am going to describe,
but this illustrates the problem.

I have two threads: the UI thread and a polling (worker) thread. The
polling thread goes round and round updating the UI with information
it reads from a serial port, based on messages it reads from a
queue. Before it reads from the queue, it gets a lock on it
(SyncLock) to synchronise adding and removing items. If the queue
contains a message it is removed, the serial port is read, the UI is
updated, and the lock is released (End SyncLock).


I think I can see what is coming...
The UI sits happily, displaying the latest information.

Because the polling thread is not the UI thread (obviously) it can't
just stuff things onto the screen. So, when it updates a textbox,
for example, it uses a delegate and calls Textbox1.Invoke. Great ...
fine, so far.

Now, the user comes along (bless him), and clicks a button. This is
the signal that a message must be added to the queue. So, the UI
calls a method to add a message to the queue. Before accessing the
queue, the UI thread gets a lock on the queue, adds its message,
pulses the queue, and releases the lock. Still sounding good.

However, when the UI thread trys to get the lock (SyncLock again) it
can't get it straight away, because the polling thread has a lock,
and is about to update the UI. Therefore, the UI thread waits
patiently for the lock.

The polling thread, meanwhile, goes to update the UI. It finds it is
not on the UI thread, so sets up the delegate and calls Invoke ...
and is never heard from again.


Indeed.
Invoke hangs because it is now trying to marshal onto the UI thread,
but the UI thread is waiting on a lock that the polling thread
holds, so we have deadlock.

Over to you Jon / Cor / anyone :-(


Well you've done a first rate job of analysing the problem. All you
need to do now is move the call to the UI update out of the lock, and
you're home free :)

Limit yourself to only holding the lock while you absolutely have to -
for interacting with the queue. When you've read from the queue,
release the lock and *then* do whatever you need to with the object
you've just fetched, eg update the UI.

Jul 21 '05 #26
Hi Charles,

A while back that I was busy with threads, however I have not so much
synclocks as that I started the first time with threads, by just passing the
values from the queue (what a terrible word is that) to the thread and not
the biljartstick (before you correct queue) I did overcome those problems.

However I do not know of course if that is possible for you.

Cor
Jul 21 '05 #27
Charles Law <bl***@nowhere.com> wrote:
Hmm. I know you're right ... but ...

I deliberately kept the whole 'read message / update UI' thing inside the
SyncLock construct because it served as a way of pacing outgoing messages.

Messages have to be sent out synchronously, and the polling thread is
capable of adding messages to the queue much faster than they can be sent.
Therefore, locking the queue whilst the message was being sent seemed a
convenient way of preventing a backlog of messages from building up in the
queue. However, when the user clicks something, their request takes
precedence over the background processing, so it is legitimate to insert the
message at the head of the queue and not have to wait.

Can you think of another way round this?


When you send the message, you can always make the worker thread then
sleep for a short time, so that it's then ready to send or receive
again. If messages are queued faster than they're going to be sent,
there's bound to be a backlog *somewhere* - and in the queue is
probably the best place for them.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #28
Hi Cor
the thread and not the *biljartstick* (before you correct queue) I did
You've got me with this one. I'm not familiar with the word '"biljartstick".

Is is something like a snooker cue?

Charles
Cor Ligthert wrote: Hi Charles,

A while back that I was busy with threads, however I have not so much
synclocks as that I started the first time with threads, by just
passing the values from the queue (what a terrible word is that) to
the thread and not the biljartstick (before you correct queue) I did
overcome those problems.

However I do not know of course if that is possible for you.

Cor

Jul 21 '05 #29
Hi Jon

I nearly added ... I don't want to add any artifical pacing because the
timing will be purely arbitrary ... but I didn't.

The number of messages being sent by the polling thread is not important,
only that they should be sent without gaps. The polling messages are all he
same, so all I need to do is ensure that there is always a polling message
waiting to be sent, but no more.

Charles
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
Hmm. I know you're right ... but ...

I deliberately kept the whole 'read message / update UI' thing
inside the SyncLock construct because it served as a way of pacing
outgoing messages.

Messages have to be sent out synchronously, and the polling thread is
capable of adding messages to the queue much faster than they can be
sent. Therefore, locking the queue whilst the message was being sent
seemed a convenient way of preventing a backlog of messages from
building up in the queue. However, when the user clicks something,
their request takes precedence over the background processing, so it
is legitimate to insert the message at the head of the queue and not
have to wait.

Can you think of another way round this?


When you send the message, you can always make the worker thread then
sleep for a short time, so that it's then ready to send or receive
again. If messages are queued faster than they're going to be sent,
there's bound to be a backlog *somewhere* - and in the queue is
probably the best place for them.

Jul 21 '05 #30
Charles Law <bl***@nowhere.com> wrote:
I nearly added ... I don't want to add any artifical pacing because the
timing will be purely arbitrary ... but I didn't.

The number of messages being sent by the polling thread is not important,
only that they should be sent without gaps. The polling messages are all he
same, so all I need to do is ensure that there is always a polling message
waiting to be sent, but no more.


I'm not sure I follow, I'm afraid. How can you determine when you can
next send a message? It sounds like that's the crux of the problem.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #31
I just need a continuous stream of polling messages to be sent out. Each new
message can be sent when the last one has been acknowledged (by the remote
end). However, the user can add a non-polling message to the queue, in which
case that is sent amid the stream of polling messages.

Charles
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I nearly added ... I don't want to add any artifical pacing because
the timing will be purely arbitrary ... but I didn't.

The number of messages being sent by the polling thread is not
important, only that they should be sent without gaps. The polling
messages are all he same, so all I need to do is ensure that there
is always a polling message waiting to be sent, but no more.


I'm not sure I follow, I'm afraid. How can you determine when you can
next send a message? It sounds like that's the crux of the problem.

Jul 21 '05 #32
Hi Charles,

Yes cue, I don't know why, however for me it is sounds always something the
same as queue when I hear those guys (that commenter you know the one with
that shiny head) on BBC talking when there is snooker. (However maybe I
think about that).

Cor
Jul 21 '05 #33
Charles Law <bl***@nowhere.com> wrote:
I just need a continuous stream of polling messages to be sent out. Each new
message can be sent when the last one has been acknowledged (by the remote
end). However, the user can add a non-polling message to the queue, in which
case that is sent amid the stream of polling messages.


In which case, the synchronization you need is between the polling
thread and the acknowledgement. You might want to do this with events,
for instance, firing an event whenever an acknowledgement is received,
and subscribing to that event with a delegate which adds a message to
the queue - possibly only if there isn't one there already.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #34
Hi Jon

You certainly appear to have grasped the nub of the problem. But I am guilty
of misleading in one respect.

When I said that the polling messages are all the same, I wasn't quite
telling the truth. They rotate round about 16 different messages, so the
first poll is type 1, the second type 2, and so on, up to 16. Then they
start again. The sequence is important, and there must not be any omissions.
So I do need to carefully synchronise the polling with the acknowledgements,
as well as the intermittent UI messages.

I like the idea of using an event to get the next polling message (rather
like the TxBufferEmpty interrupt from a UART). I am also looking at creating
a dedicated queue class to maintain the messages, rather than use the
standard Queue class, in particular to allow me to insert messages ahead of
any polling messages (something the standard class doesn't allow). For this
reason, I am inheriting from CollectionBase rather than Queue, unless you
know of a better one.

Charles
[By the way, thanks for your continued help]
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I just need a continuous stream of polling messages to be sent out.
Each new message can be sent when the last one has been acknowledged
(by the remote end). However, the user can add a non-polling message
to the queue, in which case that is sent amid the stream of polling
messages.


In which case, the synchronization you need is between the polling
thread and the acknowledgement. You might want to do this with events,
for instance, firing an event whenever an acknowledgement is received,
and subscribing to that event with a delegate which adds a message to
the queue - possibly only if there isn't one there already.

Jul 21 '05 #35
Charles Law <bl***@nowhere.com> wrote:
You certainly appear to have grasped the nub of the problem. But I am guilty
of misleading in one respect.

When I said that the polling messages are all the same, I wasn't quite
telling the truth. They rotate round about 16 different messages, so the
first poll is type 1, the second type 2, and so on, up to 16. Then they
start again. The sequence is important, and there must not be any omissions.
So I do need to carefully synchronise the polling with the acknowledgements,
as well as the intermittent UI messages.
Right. That suggests having a concept of a "next polling message" - but
you only add that to the queue if the queue is empty at the time (or
maybe if it only has, say, fewer than 3 entries).
I like the idea of using an event to get the next polling message (rather
like the TxBufferEmpty interrupt from a UART). I am also looking at creating
a dedicated queue class to maintain the messages, rather than use the
standard Queue class, in particular to allow me to insert messages ahead of
any polling messages (something the standard class doesn't allow). For this
reason, I am inheriting from CollectionBase rather than Queue, unless you
know of a better one.


Inheriting from CollectionBase sounds like a fine idea to me.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #36
Hi, Charles

couple (triple) of comments
- queue can serve as starting point - you post there initial (starting)
message and user messages only
- thread checks the queue and processes next message. If it is user one -
you get what you want (you can send it) and don't need to hold lock on queue
anymore.
If it is <start poll> message - it sends first poll message and saves state
in internal member.
- when message was sent and processed thread locks queue once again and
checks if there are any message requests. If yes - they are user ones and
must be sent. If not, queue can be unlocked and thread can check state -
should it send next poll message or not.

In this scenario you don't need to hold queue for long periods of time.
Scheme could be expanded with arbitrary number of message sequences. It
reminds me a bit job scheduler, don't you agree?

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:uQ*************@TK2MSFTNGP10.phx.gbl...
Hi Jon

You certainly appear to have grasped the nub of the problem. But I am guilty of misleading in one respect.

When I said that the polling messages are all the same, I wasn't quite
telling the truth. They rotate round about 16 different messages, so the
first poll is type 1, the second type 2, and so on, up to 16. Then they
start again. The sequence is important, and there must not be any omissions. So I do need to carefully synchronise the polling with the acknowledgements, as well as the intermittent UI messages.

I like the idea of using an event to get the next polling message (rather
like the TxBufferEmpty interrupt from a UART). I am also looking at creating a dedicated queue class to maintain the messages, rather than use the
standard Queue class, in particular to allow me to insert messages ahead of any polling messages (something the standard class doesn't allow). For this reason, I am inheriting from CollectionBase rather than Queue, unless you
know of a better one.

Charles
[By the way, thanks for your continued help]
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I just need a continuous stream of polling messages to be sent out.
Each new message can be sent when the last one has been acknowledged
(by the remote end). However, the user can add a non-polling message
to the queue, in which case that is sent amid the stream of polling
messages.


In which case, the synchronization you need is between the polling
thread and the acknowledgement. You might want to do this with events,
for instance, firing an event whenever an acknowledgement is received,
and subscribing to that event with a delegate which adds a message to
the queue - possibly only if there isn't one there already.


Jul 21 '05 #37
Hi Alex

All the comments are useful and appreciated. I am trying to think of a way
for the queue object to block the polling thread until the queue is empty
when it tries to add a message, but allow messages from the UI thread to be
added to the queue immediately without blocking. If I can make it all
internal to the queue class then the queue can manage itself, rather than
rely on correct implementation in the external code where messages are added
and removed. The queue will also remove non-polling messages from the queue
first, when its DeQueue method is called, and then any remaining polling
messages.

Charles
AlexS wrote:
Hi, Charles

couple (triple) of comments
- queue can serve as starting point - you post there initial
(starting) message and user messages only
- thread checks the queue and processes next message. If it is user
one - you get what you want (you can send it) and don't need to hold
lock on queue anymore.
If it is <start poll> message - it sends first poll message and saves
state in internal member.
- when message was sent and processed thread locks queue once again
and checks if there are any message requests. If yes - they are user
ones and must be sent. If not, queue can be unlocked and thread can
check state - should it send next poll message or not.

In this scenario you don't need to hold queue for long periods of
time. Scheme could be expanded with arbitrary number of message
sequences. It reminds me a bit job scheduler, don't you agree?

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:uQ*************@TK2MSFTNGP10.phx.gbl...
Hi Jon

You certainly appear to have grasped the nub of the problem. But I
am guilty of misleading in one respect.

When I said that the polling messages are all the same, I wasn't
quite telling the truth. They rotate round about 16 different
messages, so the first poll is type 1, the second type 2, and so on,
up to 16. Then they start again. The sequence is important, and
there must not be any omissions. So I do need to carefully
synchronise the polling with the acknowledgements, as well as the
intermittent UI messages.

I like the idea of using an event to get the next polling message
(rather like the TxBufferEmpty interrupt from a UART). I am also
looking at creating a dedicated queue class to maintain the
messages, rather than use the standard Queue class, in particular to
allow me to insert messages ahead of any polling messages (something
the standard class doesn't allow). For this reason, I am inheriting
from CollectionBase rather than Queue, unless you know of a better
one.

Charles
[By the way, thanks for your continued help]
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
I just need a continuous stream of polling messages to be sent out.
Each new message can be sent when the last one has been
acknowledged (by the remote end). However, the user can add a
non-polling message to the queue, in which case that is sent amid
the stream of polling messages.

In which case, the synchronization you need is between the polling
thread and the acknowledgement. You might want to do this with
events, for instance, firing an event whenever an acknowledgement
is received, and subscribing to that event with a delegate which
adds a message to the queue - possibly only if there isn't one
there already.

Jul 21 '05 #38
I am not sure I see the reason for "blocking polling thread until the queue
is empty".
As I see it blocking (synchronization) is required only when you check queue
status - if it has anything in - and get request out.

HTH
Alex
"Charles Law" <bl***@nowhere.com> wrote in message
news:eZ**************@TK2MSFTNGP10.phx.gbl...
Hi Alex

All the comments are useful and appreciated. I am trying to think of a way
for the queue object to block the polling thread until the queue is empty
when it tries to add a message, but allow messages from the UI thread to be added to the queue immediately without blocking. If I can make it all
internal to the queue class then the queue can manage itself, rather than
rely on correct implementation in the external code where messages are added and removed. The queue will also remove non-polling messages from the queue first, when its DeQueue method is called, and then any remaining polling
messages.

Charles
AlexS wrote:
Hi, Charles

couple (triple) of comments
- queue can serve as starting point - you post there initial
(starting) message and user messages only
- thread checks the queue and processes next message. If it is user
one - you get what you want (you can send it) and don't need to hold
lock on queue anymore.
If it is <start poll> message - it sends first poll message and saves
state in internal member.
- when message was sent and processed thread locks queue once again
and checks if there are any message requests. If yes - they are user
ones and must be sent. If not, queue can be unlocked and thread can
check state - should it send next poll message or not.

In this scenario you don't need to hold queue for long periods of
time. Scheme could be expanded with arbitrary number of message
sequences. It reminds me a bit job scheduler, don't you agree?

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:uQ*************@TK2MSFTNGP10.phx.gbl...
Hi Jon

You certainly appear to have grasped the nub of the problem. But I
am guilty of misleading in one respect.

When I said that the polling messages are all the same, I wasn't
quite telling the truth. They rotate round about 16 different
messages, so the first poll is type 1, the second type 2, and so on,
up to 16. Then they start again. The sequence is important, and
there must not be any omissions. So I do need to carefully
synchronise the polling with the acknowledgements, as well as the
intermittent UI messages.

I like the idea of using an event to get the next polling message
(rather like the TxBufferEmpty interrupt from a UART). I am also
looking at creating a dedicated queue class to maintain the
messages, rather than use the standard Queue class, in particular to
allow me to insert messages ahead of any polling messages (something
the standard class doesn't allow). For this reason, I am inheriting
from CollectionBase rather than Queue, unless you know of a better
one.

Charles
[By the way, thanks for your continued help]
Jon Skeet [C# MVP] wrote:
Charles Law <bl***@nowhere.com> wrote:
> I just need a continuous stream of polling messages to be sent out.
> Each new message can be sent when the last one has been
> acknowledged (by the remote end). However, the user can add a
> non-polling message to the queue, in which case that is sent amid
> the stream of polling messages.

In which case, the synchronization you need is between the polling
thread and the acknowledgement. You might want to do this with
events, for instance, firing an event whenever an acknowledgement
is received, and subscribing to that event with a delegate which
adds a message to the queue - possibly only if there isn't one
there already.


Jul 21 '05 #39
Hi Charles,

Did you already think on an extra thread, which handles the queues

And than only threads for handling the messages

Just thinking with you

Cor
Jul 21 '05 #40
Hi Cor

I think that is what I have effectively, yes.

The UI thread sits around doing nothing most of the time. Occasionally, it
picks up a message to add to the queue from the user.

The polling thread goes round and round, feeding polling messages into the
queue when it can.

A despatcher thread waits for a message to appear in the queue, and when one
appears it sends it to the serial comms routines.

The comms module has a receiver thread, which collects data from the port,
and raises events to signal when it has something.

Those are the four threads that I currently have. I am now looking at how I
can block the polling thread whilst there are messages in the queue, so that
it does not fill the queue faster than it can be emptied.

Charles
Cor Ligthert wrote:
Hi Charles,

Did you already think on an extra thread, which handles the queues

And than only threads for handling the messages

Just thinking with you

Cor

Jul 21 '05 #41
Hi Alex

I thought of blocking the thread as a way of pacing polling messages.
Because the polling thread can add messages faster than they can be sent, I
want to avoid a build-up. If I only put polling messages in the queue when
it is empty, for example, I would miss out some messages in the sequence.

The polling thread is basically a For Each loop inside a Do While True loop.
The inner loop gets the sequence of polling messages, but if the queue has
messages waiting and I were to skip a message I would get out of sync (with
the messages).

Charles
AlexS wrote:
I am not sure I see the reason for "blocking polling thread until the
queue is empty".
As I see it blocking (synchronization) is required only when you
check queue status - if it has anything in - and get request out.

HTH
Alex
"Charles Law" <bl***@nowhere.com> wrote in message
news:eZ**************@TK2MSFTNGP10.phx.gbl...
Hi Alex

All the comments are useful and appreciated. I am trying to think of
a way for the queue object to block the polling thread until the
queue is empty when it tries to add a message, but allow messages
from the UI thread to be added to the queue immediately without
blocking. If I can make it all internal to the queue class then the
queue can manage itself, rather than rely on correct implementation
in the external code where messages are added and removed. The queue
will also remove non-polling messages from the queue first, when its
DeQueue method is called, and then any remaining polling messages.

Charles
AlexS wrote:
Hi, Charles

couple (triple) of comments
- queue can serve as starting point - you post there initial
(starting) message and user messages only
- thread checks the queue and processes next message. If it is user
one - you get what you want (you can send it) and don't need to hold
lock on queue anymore.
If it is <start poll> message - it sends first poll message and
saves state in internal member.
- when message was sent and processed thread locks queue once again
and checks if there are any message requests. If yes - they are user
ones and must be sent. If not, queue can be unlocked and thread can
check state - should it send next poll message or not.

In this scenario you don't need to hold queue for long periods of
time. Scheme could be expanded with arbitrary number of message
sequences. It reminds me a bit job scheduler, don't you agree?

HTH
Alex

"Charles Law" <bl***@nowhere.com> wrote in message
news:uQ*************@TK2MSFTNGP10.phx.gbl...
Hi Jon

You certainly appear to have grasped the nub of the problem. But I
am guilty of misleading in one respect.

When I said that the polling messages are all the same, I wasn't
quite telling the truth. They rotate round about 16 different
messages, so the first poll is type 1, the second type 2, and so
on, up to 16. Then they start again. The sequence is important, and
there must not be any omissions. So I do need to carefully
synchronise the polling with the acknowledgements, as well as the
intermittent UI messages.

I like the idea of using an event to get the next polling message
(rather like the TxBufferEmpty interrupt from a UART). I am also
looking at creating a dedicated queue class to maintain the
messages, rather than use the standard Queue class, in particular
to allow me to insert messages ahead of any polling messages
(something the standard class doesn't allow). For this reason, I
am inheriting from CollectionBase rather than Queue, unless you
know of a better one.

Charles
[By the way, thanks for your continued help]
Jon Skeet [C# MVP] wrote:
> Charles Law <bl***@nowhere.com> wrote:
>> I just need a continuous stream of polling messages to be sent
>> out. Each new message can be sent when the last one has been
>> acknowledged (by the remote end). However, the user can add a
>> non-polling message to the queue, in which case that is sent amid
>> the stream of polling messages.
>
> In which case, the synchronization you need is between the polling
> thread and the acknowledgement. You might want to do this with
> events, for instance, firing an event whenever an acknowledgement
> is received, and subscribing to that event with a delegate which
> adds a message to the queue - possibly only if there isn't one
> there already.

Jul 21 '05 #42
Hi Charles,

I hope this is not a stuppid answer, however I was as well searching very
long for something like that and when I saw that

threading.thread.sleep(1000)

It was the answer for me by doing it in a do loop,

First I got a lot of comments in this newsgroup using it in samples and now
you see it more and more.

(I have somewhere placed your name in a message about the AX webbrowser, can
you have a look at that?)

Cor
Jul 21 '05 #43
Cor Ligthert wrote:
Hi Charles,

I hope this is not a stuppid answer, however I was as well searching
very long for something like that and when I saw that

threading.thread.sleep(1000)

It was the answer for me by doing it in a do loop,

First I got a lot of comments in this newsgroup using it in samples
and now you see it more and more.

(I have somewhere placed your name in a message about the AX
webbrowser, can you have a look at that?)

Cor

Jul 21 '05 #44
Hi Cor

I hit the send button by mistake on a blank message <:-(

I'm reluctant to use a sleep() in this situation because the value would be
purely arbitrary. I need the messages to go as close together as possible,
and if I put in a sleep of 1 second I will have gaps. I could make it lower,
but how low? It becomes a matter of trial and error, and therefore not very
precise. At least if I block the thread I know that the next message will be
sent as soon as possible, no sooner nor later.

I will have a look for that other message.

Regards

Charles
Cor Ligthert wrote:
Hi Charles,

I hope this is not a stuppid answer, however I was as well searching
very long for something like that and when I saw that

threading.thread.sleep(1000)

It was the answer for me by doing it in a do loop,

First I got a lot of comments in this newsgroup using it in samples
and now you see it more and more.

(I have somewhere placed your name in a message about the AX
webbrowser, can you have a look at that?)

Cor

Jul 21 '05 #45

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

44
by: Charles Law | last post by:
Hi guys. I'm back on the threading gig again. It's the age-old question about waiting for something to happen without wasting time doing it. Take two threads: the main thread and a worker...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.