Separate threads only run with DoEvents

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Charles Law

    Separate threads only run with DoEvents

    I know I have brought this one up before, but I didn't get an answer last
    time, so hopefully I will have better luck this time.

    I send data out of a serial port on my main thread. I wait for a response on
    a background thread. While my main thread is waiting (only 100ms) it sits in
    a loop calling DoEvents and testing a flag.

    The background thread looks at the incoming data, and when it recognises
    something it sets a flag.

    Meanwhile, the main thread sees that the flag has been set and processes the
    response. All well and good.

    But if I replace the call to DoEvents with Thread.Sleep(10 ) it doesn't work
    anymore. The background thread never gets a sniff at the data. Why would
    that be? I thought the point of multi-threading was that you didn't need to
    'yield' to allow another thread to get processing time.

    Incidentally, please feel free to criticise the overall technique I have
    described. I'm not totally happy with it myself, so any suggestions are
    welcome.

    TIA

    Charles


  • Klaus Löffelmann

    #2
    Re: Separate threads only run with DoEvents

    Charles,

    how does the background thread receive the data. Is it somehow connected to
    the message pump of the UI-Thread?

    Klaus

    "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
    news:%23FcthK5I EHA.3820@tk2msf tngp13.phx.gbl. ..[color=blue]
    > I know I have brought this one up before, but I didn't get an answer last
    > time, so hopefully I will have better luck this time.
    >
    > I send data out of a serial port on my main thread. I wait for a response[/color]
    on[color=blue]
    > a background thread. While my main thread is waiting (only 100ms) it sits[/color]
    in[color=blue]
    > a loop calling DoEvents and testing a flag.
    >
    > The background thread looks at the incoming data, and when it recognises
    > something it sets a flag.
    >
    > Meanwhile, the main thread sees that the flag has been set and processes[/color]
    the[color=blue]
    > response. All well and good.
    >
    > But if I replace the call to DoEvents with Thread.Sleep(10 ) it doesn't[/color]
    work[color=blue]
    > anymore. The background thread never gets a sniff at the data. Why would
    > that be? I thought the point of multi-threading was that you didn't need[/color]
    to[color=blue]
    > 'yield' to allow another thread to get processing time.
    >
    > Incidentally, please feel free to criticise the overall technique I have
    > described. I'm not totally happy with it myself, so any suggestions are
    > welcome.
    >
    > TIA
    >
    > Charles
    >
    >[/color]


    Comment

    • Charles Law

      #3
      Re: Separate threads only run with DoEvents

      Hi Klaus

      It calls WaitCommEvent and then WaitForSingleOb ject with INFINITE as the
      second parameter.

      The thread that it is on is started when the port is opened, so it is always
      looking for data. The thread is marked as IsBackground = True.

      Charles


      "Klaus Löffelmann" <fornewsgroups@ loeffelmann.de> wrote in message
      news:OMtWuN5IEH A.2480@tk2msftn gp13.phx.gbl...[color=blue]
      > Charles,
      >
      > how does the background thread receive the data. Is it somehow connected[/color]
      to[color=blue]
      > the message pump of the UI-Thread?
      >
      > Klaus
      >
      > "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
      > news:%23FcthK5I EHA.3820@tk2msf tngp13.phx.gbl. ..[color=green]
      > > I know I have brought this one up before, but I didn't get an answer[/color][/color]
      last[color=blue][color=green]
      > > time, so hopefully I will have better luck this time.
      > >
      > > I send data out of a serial port on my main thread. I wait for a[/color][/color]
      response[color=blue]
      > on[color=green]
      > > a background thread. While my main thread is waiting (only 100ms) it[/color][/color]
      sits[color=blue]
      > in[color=green]
      > > a loop calling DoEvents and testing a flag.
      > >
      > > The background thread looks at the incoming data, and when it recognises
      > > something it sets a flag.
      > >
      > > Meanwhile, the main thread sees that the flag has been set and processes[/color]
      > the[color=green]
      > > response. All well and good.
      > >
      > > But if I replace the call to DoEvents with Thread.Sleep(10 ) it doesn't[/color]
      > work[color=green]
      > > anymore. The background thread never gets a sniff at the data. Why would
      > > that be? I thought the point of multi-threading was that you didn't need[/color]
      > to[color=green]
      > > 'yield' to allow another thread to get processing time.
      > >
      > > Incidentally, please feel free to criticise the overall technique I have
      > > described. I'm not totally happy with it myself, so any suggestions are
      > > welcome.
      > >
      > > TIA
      > >
      > > Charles
      > >
      > >[/color]
      >
      >[/color]


      Comment

      • NM

        #4
        Re: Separate threads only run with DoEvents

        Hope this link will help you :





        Comment

        • Armin Zingler

          #5
          Re: Separate threads only run with DoEvents

          "Charles Law" <blank@nowhere. com> schrieb[color=blue]
          > I know I have brought this one up before, but I didn't get an answer
          > last time, so hopefully I will have better luck this time.
          >
          > I send data out of a serial port on my main thread. I wait for a
          > response on a background thread. While my main thread is waiting
          > (only 100ms) it sits in a loop calling DoEvents and testing a
          > flag.
          >
          > The background thread looks at the incoming data, and when it
          > recognises something it sets a flag.
          >
          > Meanwhile, the main thread sees that the flag has been set and
          > processes the response. All well and good.
          >
          > But if I replace the call to DoEvents with Thread.Sleep(10 ) it
          > doesn't work anymore. The background thread never gets a sniff at the
          > data. Why would that be? I thought the point of multi-threading was
          > that you didn't need to 'yield' to allow another thread to get
          > processing time.
          >
          > Incidentally, please feel free to criticise the overall technique I
          > have described. I'm not totally happy with it myself, so any
          > suggestions are welcome.[/color]



          As the docs to WaitForSingleOb ject say, you must process the
          windows messages if you've got a UI thread. Otherwise "use
          MsgWaitForMulti pleObjects or MsgWaitForMulti pleObjectsEx, rather than
          WaitForSingleOb ject"


          --
          Armin

          How to quote and why:



          Comment

          • Klaus Löffelmann

            #6
            Re: Separate threads only run with DoEvents

            Charles,

            see Armins reply.

            Klaus

            "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
            news:uADy$Y5IEH A.3040@TK2MSFTN GP09.phx.gbl...[color=blue]
            > Hi Klaus
            >
            > It calls WaitCommEvent and then WaitForSingleOb ject with INFINITE as the
            > second parameter.
            >
            > The thread that it is on is started when the port is opened, so it is[/color]
            always[color=blue]
            > looking for data. The thread is marked as IsBackground = True.
            >
            > Charles
            >
            >
            > "Klaus Löffelmann" <fornewsgroups@ loeffelmann.de> wrote in message
            > news:OMtWuN5IEH A.2480@tk2msftn gp13.phx.gbl...[color=green]
            > > Charles,
            > >
            > > how does the background thread receive the data. Is it somehow connected[/color]
            > to[color=green]
            > > the message pump of the UI-Thread?
            > >
            > > Klaus
            > >
            > > "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
            > > news:%23FcthK5I EHA.3820@tk2msf tngp13.phx.gbl. ..[color=darkred]
            > > > I know I have brought this one up before, but I didn't get an answer[/color][/color]
            > last[color=green][color=darkred]
            > > > time, so hopefully I will have better luck this time.
            > > >
            > > > I send data out of a serial port on my main thread. I wait for a[/color][/color]
            > response[color=green]
            > > on[color=darkred]
            > > > a background thread. While my main thread is waiting (only 100ms) it[/color][/color]
            > sits[color=green]
            > > in[color=darkred]
            > > > a loop calling DoEvents and testing a flag.
            > > >
            > > > The background thread looks at the incoming data, and when it[/color][/color][/color]
            recognises[color=blue][color=green][color=darkred]
            > > > something it sets a flag.
            > > >
            > > > Meanwhile, the main thread sees that the flag has been set and[/color][/color][/color]
            processes[color=blue][color=green]
            > > the[color=darkred]
            > > > response. All well and good.
            > > >
            > > > But if I replace the call to DoEvents with Thread.Sleep(10 ) it doesn't[/color]
            > > work[color=darkred]
            > > > anymore. The background thread never gets a sniff at the data. Why[/color][/color][/color]
            would[color=blue][color=green][color=darkred]
            > > > that be? I thought the point of multi-threading was that you didn't[/color][/color][/color]
            need[color=blue][color=green]
            > > to[color=darkred]
            > > > 'yield' to allow another thread to get processing time.
            > > >
            > > > Incidentally, please feel free to criticise the overall technique I[/color][/color][/color]
            have[color=blue][color=green][color=darkred]
            > > > described. I'm not totally happy with it myself, so any suggestions[/color][/color][/color]
            are[color=blue][color=green][color=darkred]
            > > > welcome.
            > > >
            > > > TIA
            > > >
            > > > Charles
            > > >
            > > >[/color]
            > >
            > >[/color]
            >
            >[/color]


            Comment

            • Charles Law

              #7
              Re: Separate threads only run with DoEvents

              Thanks Klaus.


              "Klaus Löffelmann" <fornewsgroups@ loeffelmann.de> wrote in message
              news:ukCkqC7IEH A.2764@TK2MSFTN GP10.phx.gbl...[color=blue]
              > Charles,
              >
              > see Armins reply.
              >
              > Klaus
              >
              > "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
              > news:uADy$Y5IEH A.3040@TK2MSFTN GP09.phx.gbl...[color=green]
              > > Hi Klaus
              > >
              > > It calls WaitCommEvent and then WaitForSingleOb ject with INFINITE as the
              > > second parameter.
              > >
              > > The thread that it is on is started when the port is opened, so it is[/color]
              > always[color=green]
              > > looking for data. The thread is marked as IsBackground = True.
              > >
              > > Charles
              > >
              > >
              > > "Klaus Löffelmann" <fornewsgroups@ loeffelmann.de> wrote in message
              > > news:OMtWuN5IEH A.2480@tk2msftn gp13.phx.gbl...[color=darkred]
              > > > Charles,
              > > >
              > > > how does the background thread receive the data. Is it somehow[/color][/color][/color]
              connected[color=blue][color=green]
              > > to[color=darkred]
              > > > the message pump of the UI-Thread?
              > > >
              > > > Klaus
              > > >
              > > > "Charles Law" <blank@nowhere. com> schrieb im Newsbeitrag
              > > > news:%23FcthK5I EHA.3820@tk2msf tngp13.phx.gbl. ..
              > > > > I know I have brought this one up before, but I didn't get an answer[/color]
              > > last[color=darkred]
              > > > > time, so hopefully I will have better luck this time.
              > > > >
              > > > > I send data out of a serial port on my main thread. I wait for a[/color]
              > > response[color=darkred]
              > > > on
              > > > > a background thread. While my main thread is waiting (only 100ms) it[/color]
              > > sits[color=darkred]
              > > > in
              > > > > a loop calling DoEvents and testing a flag.
              > > > >
              > > > > The background thread looks at the incoming data, and when it[/color][/color]
              > recognises[color=green][color=darkred]
              > > > > something it sets a flag.
              > > > >
              > > > > Meanwhile, the main thread sees that the flag has been set and[/color][/color]
              > processes[color=green][color=darkred]
              > > > the
              > > > > response. All well and good.
              > > > >
              > > > > But if I replace the call to DoEvents with Thread.Sleep(10 ) it[/color][/color][/color]
              doesn't[color=blue][color=green][color=darkred]
              > > > work
              > > > > anymore. The background thread never gets a sniff at the data. Why[/color][/color]
              > would[color=green][color=darkred]
              > > > > that be? I thought the point of multi-threading was that you didn't[/color][/color]
              > need[color=green][color=darkred]
              > > > to
              > > > > 'yield' to allow another thread to get processing time.
              > > > >
              > > > > Incidentally, please feel free to criticise the overall technique I[/color][/color]
              > have[color=green][color=darkred]
              > > > > described. I'm not totally happy with it myself, so any suggestions[/color][/color]
              > are[color=green][color=darkred]
              > > > > welcome.
              > > > >
              > > > > TIA
              > > > >
              > > > > Charles
              > > > >
              > > > >
              > > >
              > > >[/color]
              > >
              > >[/color]
              >
              >[/color]


              Comment

              • Charles Law

                #8
                Re: Separate threads only run with DoEvents

                Hi Armin

                My receive thread does not have a UI. Do you mean that I still have to use
                MsgWaitForMulti pleObjects? I don't see how that will help. Doesn't that just
                mean that the call to MsgWaitForMulti pleObjects will return when there is a
                Windows message to process? If so, it will terminate for a reason other than
                data being received.

                Charles


                "Armin Zingler" <az.nospam@free net.de> wrote in message
                news:407fd492$1 $12520$9b622d9e @news.freenet.d e...[color=blue]
                > "Charles Law" <blank@nowhere. com> schrieb[color=green]
                > > I know I have brought this one up before, but I didn't get an answer
                > > last time, so hopefully I will have better luck this time.
                > >
                > > I send data out of a serial port on my main thread. I wait for a
                > > response on a background thread. While my main thread is waiting
                > > (only 100ms) it sits in a loop calling DoEvents and testing a
                > > flag.
                > >
                > > The background thread looks at the incoming data, and when it
                > > recognises something it sets a flag.
                > >
                > > Meanwhile, the main thread sees that the flag has been set and
                > > processes the response. All well and good.
                > >
                > > But if I replace the call to DoEvents with Thread.Sleep(10 ) it
                > > doesn't work anymore. The background thread never gets a sniff at the
                > > data. Why would that be? I thought the point of multi-threading was
                > > that you didn't need to 'yield' to allow another thread to get
                > > processing time.
                > >
                > > Incidentally, please feel free to criticise the overall technique I
                > > have described. I'm not totally happy with it myself, so any
                > > suggestions are welcome.[/color]
                >
                >
                >
                > As the docs to WaitForSingleOb ject say, you must process the
                > windows messages if you've got a UI thread. Otherwise "use
                > MsgWaitForMulti pleObjects or MsgWaitForMulti pleObjectsEx, rather than
                > WaitForSingleOb ject"
                >
                >
                > --
                > Armin
                >
                > How to quote and why:
                > http://www.plig.net/nnq/nquote.html
                > http://www.netmeister.org/news/learn2quote.html
                >[/color]


                Comment

                • Charles Law

                  #9
                  Re: Separate threads only run with DoEvents

                  Thanks. I have seen something similar to this before, but it is useful.

                  Charles


                  "NM" <NM_656@hotmail .com> wrote in message
                  news:%23uoi996I EHA.3820@tk2msf tngp13.phx.gbl. ..[color=blue]
                  > Hope this link will help you :
                  >
                  > http://www.devx.com/getHelpOn/10MinuteSolution/20365
                  >
                  >
                  >[/color]


                  Comment

                  • Armin Zingler

                    #10
                    Re: Separate threads only run with DoEvents

                    "Charles Law" <blank@nowhere. com> schrieb[color=blue]
                    > Hi Armin
                    >
                    > My receive thread does not have a UI. Do you mean that I still have
                    > to use MsgWaitForMulti pleObjects? I don't see how that will help.
                    > Doesn't that just mean that the call to MsgWaitForMulti pleObjects
                    > will return when there is a Windows message to process? If so, it
                    > will terminate for a reason other than data being received.[/color]

                    Maybe WaitCommEvent makes the thread an UI thread. ;-) No, I don't know.
                    There's nothing connected to my serial port, so I can't help you here. :)


                    --
                    Armin

                    How to quote and why:



                    Comment

                    • Dick Grier

                      #11
                      Re: Separate threads only run with DoEvents

                      Hi,

                      Are you sure your background thread is, in fact, a thread? Using
                      Thread.Sleep should work, if so. I have written test code that works using
                      this technique.

                      However.. There are better designs. If you simply want to wait, why not
                      Invoke an asynchronous delegate (this still is a thread, just of a different
                      feather). When then, the calling code will wait (forever, potentially)
                      until the delegate finishes. The delegate should have a built-in timeout,
                      so that it doesn't block the calling code if there is a failure to receive
                      the expected return data. Other UI elements will not be affected by the
                      call to the delegate.

                      Or, you can do what I prefer to do in certain designs, and that is to raise
                      an event from my thread, which notifies me when it is ready to return data.

                      If your design is a common state-machine: Send a command, Wait for a
                      response, then the Asynchronous Delegate approach really stands out. If
                      your design is more complex, where the thread may want to return a variety
                      of data at arbitrary times, then a free thread, event mechanism makes sense.
                      IMO.

                      The basic problem with waiting for some arbitrary amount of time is that you
                      always guess on the long side. Thus, your code is not as responsive as it
                      might be.

                      BTW, DoEvents is/are not a bad thing, though it/they can cause side effects
                      (and often should be coupled with Sleep, anyway). None-the-less, .NET
                      provides more efficient ways that DoEvents loops, so it behooves us to use
                      them for robust designs.

                      Dick
                      --
                      Richard Grier (Microsoft Visual Basic MVP)

                      See www.hardandsoftware.net for contact information.

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


                      Comment

                      • Charles Law

                        #12
                        Re: Separate threads only run with DoEvents

                        Hi Dick

                        You make the kind of suggestions that set me thinking. I think I should look
                        closer at asynchronous delegates.

                        My scenario is actually not complicated. I have a polling thread, that sends
                        messages and expects a response for each message. The process must be
                        synchronous because this is how the receiving end operates. Data can change
                        with each poll, so the faster I can send and receive a message the smoother
                        the effect at the UI (although the polling thread is not the same as the UI
                        thread, data is processed and passed to the UI thread).

                        The user can also interact with the application in such a way that messages
                        are sent to the receiving end and the response is displayed on-screen.

                        So, I actually have three threads running: UI (main), polling, and reading
                        data from comms.

                        The reading data thread raises an event to the UI or polling thread
                        (whichever sent the message) whereupon the response is processed.

                        Because of the synchronous nature of the receiver, I have to wait before I
                        can send another message out. And I have to wait for a response so that I
                        can update the UI.

                        From this description, does 'asynchronous delegate' sound like a good
                        candidate? If presume that when the calling code invokes the delegate, the
                        problem of waiting is then shifted to the delegate. What method would the
                        delegate use for waiting? It seems to me that somewhere - even if it is in
                        the delegate - there has to be a loop that tests for some event, and exits
                        when the event occurs, or a timeout occurs.

                        Do you have a simple example of an asynchronous delegate that I could adapt
                        for my scenario? In particular, I am interested in your suggestion that
                        ".NET provides more efficient ways than DoEvents loops". Could you
                        elaborate?

                        Thanks.

                        Charles


                        "Dick Grier" <dick_grierNOSP AM@msn.com> wrote in message
                        news:u9KwXN$IEH A.2880@TK2MSFTN GP10.phx.gbl...[color=blue]
                        > Hi,
                        >
                        > Are you sure your background thread is, in fact, a thread? Using
                        > Thread.Sleep should work, if so. I have written test code that works[/color]
                        using[color=blue]
                        > this technique.
                        >
                        > However.. There are better designs. If you simply want to wait, why not
                        > Invoke an asynchronous delegate (this still is a thread, just of a[/color]
                        different[color=blue]
                        > feather). When then, the calling code will wait (forever, potentially)
                        > until the delegate finishes. The delegate should have a built-in timeout,
                        > so that it doesn't block the calling code if there is a failure to receive
                        > the expected return data. Other UI elements will not be affected by the
                        > call to the delegate.
                        >
                        > Or, you can do what I prefer to do in certain designs, and that is to[/color]
                        raise[color=blue]
                        > an event from my thread, which notifies me when it is ready to return[/color]
                        data.[color=blue]
                        >
                        > If your design is a common state-machine: Send a command, Wait for a
                        > response, then the Asynchronous Delegate approach really stands out. If
                        > your design is more complex, where the thread may want to return a variety
                        > of data at arbitrary times, then a free thread, event mechanism makes[/color]
                        sense.[color=blue]
                        > IMO.
                        >
                        > The basic problem with waiting for some arbitrary amount of time is that[/color]
                        you[color=blue]
                        > always guess on the long side. Thus, your code is not as responsive as it
                        > might be.
                        >
                        > BTW, DoEvents is/are not a bad thing, though it/they can cause side[/color]
                        effects[color=blue]
                        > (and often should be coupled with Sleep, anyway). None-the-less, .NET
                        > provides more efficient ways that DoEvents loops, so it behooves us to use
                        > them for robust designs.
                        >
                        > Dick
                        > --
                        > Richard Grier (Microsoft Visual Basic MVP)
                        >
                        > See www.hardandsoftware.net for contact information.
                        >
                        > Author of Visual Basic Programmer's Guide to Serial Communications, 3rd
                        > Edition ISBN 1-890422-27-4 (391 pages) published February 2002.
                        >
                        >[/color]


                        Comment

                        Working...