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 44 2167
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
> 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
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
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.
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
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.
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.
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
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
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
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.
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
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.
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
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
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.
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
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.
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.
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.
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
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
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.
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
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: Matthew3360 |
last post by:
Hi,
I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: Carina712 |
last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: ezappsrUS |
last post by:
Hi,
I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
| |