Threading questions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • **Developer**

    Threading questions

    I have a simple need that I can't seem to locate the answer to in the docs.
    Most examples show how a worker thread can pass data back to the thread that
    created it.

    I need to do the opposite.
    Suppose the worker thread displays a form and the thread that created it
    wants to change that form's text occasionally.



    Can't seem to locate a simple way of doing that.



    Thanks in advance



  • Ernie Otero

    #2
    Re: Threading questions

    Hope this helps....
    The example is in C++ but the concept should be the same in VB



    **Developer** wrote:[color=blue]
    > I have a simple need that I can't seem to locate the answer to in the docs.
    > Most examples show how a worker thread can pass data back to the thread that
    > created it.
    >
    > I need to do the opposite.
    > Suppose the worker thread displays a form and the thread that created it
    > wants to change that form's text occasionally.
    >
    >
    >
    > Can't seem to locate a simple way of doing that.
    >
    >
    >
    > Thanks in advance
    >
    >
    >[/color]

    Comment

    • **Developer**

      #3
      Re: Threading questions

      I don't have a problem starting a thread and passing it parameters.
      It's after the thread is started I need to pass data to it - that's what I
      don't know how to do.


      Thanks for replying


      "Ernie Otero" <eoteroNOSPAM@d sli.com> wrote in message
      news:8_-dnZ0_I_O7ukDeRV n-tg@dsli.com...[color=blue]
      > Hope this helps....
      > The example is in C++ but the concept should be the same in VB
      >
      > http://www.codeproject.com/managedcpp/mcppthreads01.asp
      >
      > **Developer** wrote:[color=green]
      >> I have a simple need that I can't seem to locate the answer to in the
      >> docs.
      >> Most examples show how a worker thread can pass data back to the thread
      >> that created it.
      >>
      >> I need to do the opposite.
      >> Suppose the worker thread displays a form and the thread that created it
      >> wants to change that form's text occasionally.
      >>
      >>
      >>
      >> Can't seem to locate a simple way of doing that.
      >>
      >>
      >>
      >> Thanks in advance
      >>
      >>[/color][/color]

      Comment

      • Jay B. Harlow [MVP - Outlook]

        #4
        Re: Threading questions

        | Suppose the worker thread displays a form and the thread that created it
        | wants to change that form's text occasionally.
        If the worker thread is showing a Form, then you can use Control.Invoke on
        that form or one of its control to transfer information to the worker
        thread.

        Alternatively if the worker thread does not have a Form, I have used a
        System.Collecti ons.Queue to send information to a thread. The thread would
        look for information in the queue & operate on it.

        Something like (VS 2003 syntax):

        ' untested, typed from memory.
        Public Class ThreadRequestQu eue

        Private Readonly m_padlock As New Object
        Private Readonly m_queue As New Queue
        Private Readonly m_event As New AutoResetEvent( False)

        ' called from the Main thread
        Public Sub AddRequest(ByVa l request As Object)
        SyncLock m_padlock
        m_queue.Enqueue (Object)
        End SyncLock
        m_event.Set()
        End Sub

        ' called from the Worker thread
        Public Function GetRequest() As Object
        ' Check to see if there are already items available
        SyncLock m_padlock
        If m_queue.Count() > 0 Then
        Return m_queue.DeQueue ()
        End If
        End SyncLock

        ' Cannot block worker thread
        ' while waiting for the main thread to add requests
        m_event.WaitOne ()

        ' There must be an item
        SyncLock m_padlock
        Return m_queue.Dequeue ()
        End SyncLock
        End Function

        End Class

        The Queue is used to send the requests from the Main thread to the Worker
        thread. The m_padlock is used to protect the Queue.Enqueue & Queue.Dequeue
        methods. The worker thread "goes to sleep" if there are no items in the
        queue to work on, the AutoResetEvent is used to notify (wake up) the worker
        thread there are more items available.

        In VS 2005 (.NET 2.0) I would consider using a
        System.Collecti ons.Generic.Que ue(Of T) instead of the object based Queue
        above:


        --
        Hope this helps
        Jay [MVP - Outlook]
        ..NET Application Architect, Enthusiast, & Evangelist
        T.S. Bradley - http://www.tsbradley.net


        " **Developer**" <REMOVEdevelope r@a-znet.com> wrote in message
        news:OejJJ4QJGH A.344@TK2MSFTNG P11.phx.gbl...
        |I have a simple need that I can't seem to locate the answer to in the docs.
        | Most examples show how a worker thread can pass data back to the thread
        that
        | created it.
        |
        | I need to do the opposite.
        | Suppose the worker thread displays a form and the thread that created it
        | wants to change that form's text occasionally.
        |
        |
        |
        | Can't seem to locate a simple way of doing that.
        |
        |
        |
        | Thanks in advance
        |
        |
        |


        Comment

        • Brian Gideon

          #5
          Re: Threading questions

          There may be a subtle race condition in the ThreadRequestQu eue class.
          It depends on the level of thread-safety offered. As written it is
          perfectly safe for one adder and one getter simultaneously. And that's
          fine if that is it's intended use case. But, for those who may want a
          solution that offers complete thread-safety (multiple adders and
          getters) I recommend the following implementation.

          Public Class ThreadRequestQu eue

          Private Readonly m_padlock As New Object
          Private Readonly m_queue As New Queue
          Private Readonly m_event As New AutoResetEvent( False)

          ' Can be called from any thread
          Public Sub AddRequest(ByVa l request As Object)
          SyncLock m_padlock
          m_queue.Enqueue (Object)
          m_event.Set()
          End SyncLock
          End Sub

          ' Can be called from any thread
          Public Function GetRequest() As Object
          Do While True
          m_event.WaitOne ()
          SyncLock m_padlock
          If m_queue.Count > 0 Then
          Return m_queue.Dequeue ()
          End If
          End SyncLock
          Loop
          End Function

          End Class

          Brian

          Jay B. Harlow [MVP - Outlook] wrote:[color=blue]
          > | Suppose the worker thread displays a form and the thread that created it
          > | wants to change that form's text occasionally.
          > If the worker thread is showing a Form, then you can use Control.Invoke on
          > that form or one of its control to transfer information to the worker
          > thread.
          >
          > Alternatively if the worker thread does not have a Form, I have used a
          > System.Collecti ons.Queue to send information to a thread. The thread would
          > look for information in the queue & operate on it.
          >
          > Something like (VS 2003 syntax):
          >
          > ' untested, typed from memory.
          > Public Class ThreadRequestQu eue
          >
          > Private Readonly m_padlock As New Object
          > Private Readonly m_queue As New Queue
          > Private Readonly m_event As New AutoResetEvent( False)
          >
          > ' called from the Main thread
          > Public Sub AddRequest(ByVa l request As Object)
          > SyncLock m_padlock
          > m_queue.Enqueue (Object)
          > End SyncLock
          > m_event.Set()
          > End Sub
          >
          > ' called from the Worker thread
          > Public Function GetRequest() As Object
          > ' Check to see if there are already items available
          > SyncLock m_padlock
          > If m_queue.Count() > 0 Then
          > Return m_queue.DeQueue ()
          > End If
          > End SyncLock
          >
          > ' Cannot block worker thread
          > ' while waiting for the main thread to add requests
          > m_event.WaitOne ()
          >
          > ' There must be an item
          > SyncLock m_padlock
          > Return m_queue.Dequeue ()
          > End SyncLock
          > End Function
          >
          > End Class
          >
          > The Queue is used to send the requests from the Main thread to the Worker
          > thread. The m_padlock is used to protect the Queue.Enqueue & Queue.Dequeue
          > methods. The worker thread "goes to sleep" if there are no items in the
          > queue to work on, the AutoResetEvent is used to notify (wake up) the worker
          > thread there are more items available.
          >
          > In VS 2005 (.NET 2.0) I would consider using a
          > System.Collecti ons.Generic.Que ue(Of T) instead of the object based Queue
          > above:
          > http://msdn2.microsoft.com/en-us/library/7977ey2c.aspx
          >
          > --
          > Hope this helps
          > Jay [MVP - Outlook]
          > .NET Application Architect, Enthusiast, & Evangelist
          > T.S. Bradley - http://www.tsbradley.net
          >
          >
          > " **Developer**" <REMOVEdevelope r@a-znet.com> wrote in message
          > news:OejJJ4QJGH A.344@TK2MSFTNG P11.phx.gbl...
          > |I have a simple need that I can't seem to locate the answer to in the docs.
          > | Most examples show how a worker thread can pass data back to the thread
          > that
          > | created it.
          > |
          > | I need to do the opposite.
          > | Suppose the worker thread displays a form and the thread that created it
          > | wants to change that form's text occasionally.
          > |
          > |
          > |
          > | Can't seem to locate a simple way of doing that.
          > |
          > |
          > |
          > | Thanks in advance
          > |
          > |
          > |[/color]

          Comment

          • **Developer**

            #6
            Re: Threading questions

            Attached is a file containing an attempt at Threading.
            There are two uppercase questions in the file.
            Besides that I would appreciate any suggestions at all about the code -
            anything at all that might be considered better.

            It's a short, and I believe instructive because it is so short, example of
            the main thread changing state of a worker thread, and of the worker thread
            changing state of the main thread.


            Thanks in advance for


            Comment

            • Jay B. Harlow [MVP - Outlook]

              #7
              Re: Threading questions

              Brian,
              | But, for those who may want a
              | solution that offers complete thread-safety (multiple adders and
              | getters)
              The hazards of cutting & pasting a post I made a year or so ago...

              | Public Function GetRequest() As Object
              | Do While True
              | m_event.WaitOne ()
              | SyncLock m_padlock
              | If m_queue.Count > 0 Then
              | Return m_queue.Dequeue ()
              | End If
              | End SyncLock
              | Loop
              | End Function

              Your loop is superfluous! I would reduce GetRequest to:

              | Public Function GetRequest() As Object
              | m_event.WaitOne ()
              | SyncLock m_padlock
              | If m_queue.Count > 0 Then
              | Return m_queue.Dequeue ()
              | End If
              | End SyncLock
              | End Function

              Your loop is superfluous, as the m_event.WaitOne will only allow a single
              thread to pass (as its an AutoResetEvent) . The event being set indicates
              that at least a single item is in the queue. The return statement will exit
              the loop. Ergo the loop itself is superfluous. Of course! this also means
              that the "If m_queue.Count > 0 Then" is superfluous , so we can reduce it
              further to:

              | Public Function GetRequest() As Object
              | m_event.WaitOne ()
              | SyncLock m_padlock
              | Return m_queue.Dequeue ()
              | End SyncLock
              | End Function

              The "If m_queue.Count > 0 Then" is superfluous again, as the m_event.WaitOne
              will only allow a single thread to pass (as its an AutoResetEvent) ...


              However! (loop or no loop, if or no if) you just introduced a severe bug I
              was trying to avoid, all the threads block waiting for the next event,
              although there are multiple entries in the queue.

              Consider the case where one or more threads add 2 or more items to the Queue
              before any of the readers have a chance to remove the next item. There is
              only a single AutoResetEvent event, it is either set or reset. 2 items go
              in, its set, one item comes out, its reset. All the threads block for the
              third item, the third item goes in, the second item comes out, all the
              thread block for the four item, items 4 to 10 goes in, item 3 comes out...

              The way I setup GetRequest was:

              - If there are items in the queue, return the next item, only allow a single
              thread to do this! (prevent the above mentioned blockage).
              - If there are no items in the queue, wait for the event, be certain to
              allow threads to add to the queue
              - The event was set, must be an item, return the next item. *** red flag ***

              Ah! There's the rub, the first Dequeue might return the item before the
              second Dequeue has a chance to see it:

              For now I will use a variation of both of ours:

              | > ' called from the Worker thread
              | > Public Function GetRequest() As Object
              | > ' Check to see if there are already items available
              | > SyncLock m_padlock
              | > If m_queue.Count() > 0 Then
              | > Return m_queue.DeQueue ()
              | > End If
              | > End SyncLock
              | >
              | Do While True
              | m_event.WaitOne ()
              | SyncLock m_padlock
              | If m_queue.Count > 0 Then
              | Return m_queue.Dequeue ()
              | End If
              | End SyncLock
              | Loop
              | > End Function

              As this allows for the case where reader 1 gets the first Dequeue, while
              reader 2 gets the WaitOne there by missing the second Dequeue, that the
              first Dequeue just got... I wasn't considering that scenario as the original
              code was not intended for multiple readers... Thanks! for pointing it out.

              --
              Hope this helps
              Jay [MVP - Outlook]
              ..NET Application Architect, Enthusiast, & Evangelist
              T.S. Bradley - http://www.tsbradley.net


              "Brian Gideon" <briangideon@ya hoo.com> wrote in message
              news:1138639794 .059282.287610@ g14g2000cwa.goo glegroups.com.. .
              | There may be a subtle race condition in the ThreadRequestQu eue class.
              | It depends on the level of thread-safety offered. As written it is
              | perfectly safe for one adder and one getter simultaneously. And that's
              | fine if that is it's intended use case. But, for those who may want a
              | solution that offers complete thread-safety (multiple adders and
              | getters) I recommend the following implementation.
              |
              | Public Class ThreadRequestQu eue
              |
              | Private Readonly m_padlock As New Object
              | Private Readonly m_queue As New Queue
              | Private Readonly m_event As New AutoResetEvent( False)
              |
              | ' Can be called from any thread
              | Public Sub AddRequest(ByVa l request As Object)
              | SyncLock m_padlock
              | m_queue.Enqueue (Object)
              | m_event.Set()
              | End SyncLock
              | End Sub
              |
              | ' Can be called from any thread
              | Public Function GetRequest() As Object
              | Do While True
              | m_event.WaitOne ()
              | SyncLock m_padlock
              | If m_queue.Count > 0 Then
              | Return m_queue.Dequeue ()
              | End If
              | End SyncLock
              | Loop
              | End Function
              |
              | End Class
              |
              | Brian
              |
              | Jay B. Harlow [MVP - Outlook] wrote:
              | > | Suppose the worker thread displays a form and the thread that created
              it
              | > | wants to change that form's text occasionally.
              | > If the worker thread is showing a Form, then you can use Control.Invoke
              on
              | > that form or one of its control to transfer information to the worker
              | > thread.
              | >
              | > Alternatively if the worker thread does not have a Form, I have used a
              | > System.Collecti ons.Queue to send information to a thread. The thread
              would
              | > look for information in the queue & operate on it.
              | >
              | > Something like (VS 2003 syntax):
              | >
              | > ' untested, typed from memory.
              | > Public Class ThreadRequestQu eue
              | >
              | > Private Readonly m_padlock As New Object
              | > Private Readonly m_queue As New Queue
              | > Private Readonly m_event As New AutoResetEvent( False)
              | >
              | > ' called from the Main thread
              | > Public Sub AddRequest(ByVa l request As Object)
              | > SyncLock m_padlock
              | > m_queue.Enqueue (Object)
              | > End SyncLock
              | > m_event.Set()
              | > End Sub
              | >
              | > ' called from the Worker thread
              | > Public Function GetRequest() As Object
              | > ' Check to see if there are already items available
              | > SyncLock m_padlock
              | > If m_queue.Count() > 0 Then
              | > Return m_queue.DeQueue ()
              | > End If
              | > End SyncLock
              | >
              | > ' Cannot block worker thread
              | > ' while waiting for the main thread to add requests
              | > m_event.WaitOne ()
              | >
              | > ' There must be an item
              | > SyncLock m_padlock
              | > Return m_queue.Dequeue ()
              | > End SyncLock
              | > End Function
              | >
              | > End Class
              | >
              | > The Queue is used to send the requests from the Main thread to the
              Worker
              | > thread. The m_padlock is used to protect the Queue.Enqueue &
              Queue.Dequeue
              | > methods. The worker thread "goes to sleep" if there are no items in the
              | > queue to work on, the AutoResetEvent is used to notify (wake up) the
              worker
              | > thread there are more items available.
              | >
              | > In VS 2005 (.NET 2.0) I would consider using a
              | > System.Collecti ons.Generic.Que ue(Of T) instead of the object based Queue
              | > above:
              | > http://msdn2.microsoft.com/en-us/library/7977ey2c.aspx
              | >
              | > --
              | > Hope this helps
              | > Jay [MVP - Outlook]
              | > .NET Application Architect, Enthusiast, & Evangelist
              | > T.S. Bradley - http://www.tsbradley.net
              | >
              | >
              | > " **Developer**" <REMOVEdevelope r@a-znet.com> wrote in message
              | > news:OejJJ4QJGH A.344@TK2MSFTNG P11.phx.gbl...
              | > |I have a simple need that I can't seem to locate the answer to in the
              docs.
              | > | Most examples show how a worker thread can pass data back to the
              thread
              | > that
              | > | created it.
              | > |
              | > | I need to do the opposite.
              | > | Suppose the worker thread displays a form and the thread that created
              it
              | > | wants to change that form's text occasionally.
              | > |
              | > |
              | > |
              | > | Can't seem to locate a simple way of doing that.
              | > |
              | > |
              | > |
              | > | Thanks in advance
              | > |
              | > |
              | > |
              |


              Comment

              • Brian Gideon

                #8
                Re: Threading questions


                Jay B. Harlow [MVP - Outlook] wrote:[color=blue]
                > However! (loop or no loop, if or no if) you just introduced a severe bug I
                > was trying to avoid, all the threads block waiting for the next event,
                > although there are multiple entries in the queue.
                >[/color]

                Yep. I totally missed that! It demonstrates just how difficult
                synchronization can be. I think your modified solution works well.

                Comment

                • Jay B. Harlow [MVP - Outlook]

                  #9
                  Re: Threading questions

                  Brian,
                  Looking at it, we may be able to reduce it to:

                  | > ' called from the Worker thread
                  | > Public Function GetRequest() As Object
                  | Do While True
                  | > ' Check to see if there are already items available
                  | SyncLock m_padlock
                  | If m_queue.Count > 0 Then
                  | Return m_queue.Dequeue ()
                  | End If
                  | End SyncLock
                  | m_event.WaitOne ()
                  | Loop
                  | > End Function

                  If there's an item return it, otherwise wait for the event.

                  Which avoids some of the duplication in my duplicate...

                  --
                  Hope this helps
                  Jay [MVP - Outlook]
                  ..NET Application Architect, Enthusiast, & Evangelist
                  T.S. Bradley - http://www.tsbradley.net


                  "Brian Gideon" <briangideon@ya hoo.com> wrote in message
                  news:1138719457 .667529.35890@g 44g2000cwa.goog legroups.com...
                  |
                  | Jay B. Harlow [MVP - Outlook] wrote:
                  | > However! (loop or no loop, if or no if) you just introduced a severe bug
                  I
                  | > was trying to avoid, all the threads block waiting for the next event,
                  | > although there are multiple entries in the queue.
                  | >
                  |
                  | Yep. I totally missed that! It demonstrates just how difficult
                  | synchronization can be. I think your modified solution works well.
                  |


                  Comment

                  • Brian Gideon

                    #10
                    Re: Threading questions


                    Jay B. Harlow [MVP - Outlook] wrote:[color=blue]
                    > Brian,
                    > Looking at it, we may be able to reduce it to:
                    >
                    > | > ' called from the Worker thread
                    > | > Public Function GetRequest() As Object
                    > | Do While True
                    > | > ' Check to see if there are already items available
                    > | SyncLock m_padlock
                    > | If m_queue.Count > 0 Then
                    > | Return m_queue.Dequeue ()
                    > | End If
                    > | End SyncLock
                    > | m_event.WaitOne ()
                    > | Loop
                    > | > End Function
                    >
                    > If there's an item return it, otherwise wait for the event.
                    >
                    > Which avoids some of the duplication in my duplicate...
                    >[/color]

                    I took a good at it and I *think* it's okay. Jon updated his article
                    that uses Monitor.Pulse and Monitor.Wait as a solution to this problem
                    yesterday. The update was to fix a subtle bug.

                    <http://www.yoda.arachs ys.com/csharp/threads/deadlocks.shtml >

                    Brian

                    Comment

                    • swartzbill2000@yahoo.com

                      #11
                      Re: Threading questions

                      Hello,
                      As a basic question, doesn't Control.BeginIn voke() work by placing
                      messages in a queue associated with the target Thread?
                      Bill

                      Jay B. Harlow [MVP - Outlook] wrote:[color=blue]
                      > Brian,
                      > Looking at it, we may be able to reduce it to:
                      >
                      > | > ' called from the Worker thread
                      > | > Public Function GetRequest() As Object
                      > | Do While True
                      > | > ' Check to see if there are already items available
                      > | SyncLock m_padlock
                      > | If m_queue.Count > 0 Then
                      > | Return m_queue.Dequeue ()
                      > | End If
                      > | End SyncLock
                      > | m_event.WaitOne ()
                      > | Loop
                      > | > End Function
                      >
                      > If there's an item return it, otherwise wait for the event.
                      >
                      > Which avoids some of the duplication in my duplicate...
                      >
                      > --
                      > Hope this helps
                      > Jay [MVP - Outlook]
                      > .NET Application Architect, Enthusiast, & Evangelist
                      > T.S. Bradley - http://www.tsbradley.net
                      >
                      >
                      > "Brian Gideon" <briangideon@ya hoo.com> wrote in message
                      > news:1138719457 .667529.35890@g 44g2000cwa.goog legroups.com...
                      > |
                      > | Jay B. Harlow [MVP - Outlook] wrote:
                      > | > However! (loop or no loop, if or no if) you just introduced a severe bug
                      > I
                      > | > was trying to avoid, all the threads block waiting for the next event,
                      > | > although there are multiple entries in the queue.
                      > | >
                      > |
                      > | Yep. I totally missed that! It demonstrates just how difficult
                      > | synchronization can be. I think your modified solution works well.
                      > |[/color]

                      Comment

                      • Brian Gideon

                        #12
                        Re: Threading questions


                        swartzbill2000@ yahoo.com wrote:[color=blue]
                        > Hello,
                        > As a basic question, doesn't Control.BeginIn voke() work by placing
                        > messages in a queue associated with the target Thread?
                        > Bill
                        >[/color]

                        Yes. But, it only works if the target thread is running a message
                        loop. Worker threads do not typically have message loops.

                        Brian

                        Comment

                        • Jay B. Harlow [MVP - Outlook]

                          #13
                          Re: Threading questions

                          Brian,
                          Monitor might be better.

                          Just thought of a problem with my code. If there are 4 threads waiting for
                          the queue, 3 items in the queue, when the 4th item is added, only 1 thread
                          will wake up, that single thread will process all the items... I'm not sure
                          that Jon's code solves the problem, as Monitor.Pulse only releases a single
                          thread.

                          As I stated before, my code was really intended for one or more producer,
                          single consumer....

                          --
                          Hope this helps
                          Jay [MVP - Outlook]
                          ..NET Application Architect, Enthusiast, & Evangelist
                          T.S. Bradley - http://www.tsbradley.net


                          "Brian Gideon" <briangideon@ya hoo.com> wrote in message
                          news:1138891238 .272466.139120@ z14g2000cwz.goo glegroups.com.. .
                          |
                          | Jay B. Harlow [MVP - Outlook] wrote:
                          | > Brian,
                          | > Looking at it, we may be able to reduce it to:
                          | >
                          | > | > ' called from the Worker thread
                          | > | > Public Function GetRequest() As Object
                          | > | Do While True
                          | > | > ' Check to see if there are already items available
                          | > | SyncLock m_padlock
                          | > | If m_queue.Count > 0 Then
                          | > | Return m_queue.Dequeue ()
                          | > | End If
                          | > | End SyncLock
                          | > | m_event.WaitOne ()
                          | > | Loop
                          | > | > End Function
                          | >
                          | > If there's an item return it, otherwise wait for the event.
                          | >
                          | > Which avoids some of the duplication in my duplicate...
                          | >
                          |
                          | I took a good at it and I *think* it's okay. Jon updated his article
                          | that uses Monitor.Pulse and Monitor.Wait as a solution to this problem
                          | yesterday. The update was to fix a subtle bug.
                          |
                          | <http://www.yoda.arachs ys.com/csharp/threads/deadlocks.shtml >
                          |
                          | Brian
                          |


                          Comment

                          • Brian Gideon

                            #14
                            Re: Threading questions


                            Jay B. Harlow [MVP - Outlook] wrote:[color=blue]
                            > Brian,
                            > Monitor might be better.
                            >
                            > Just thought of a problem with my code. If there are 4 threads waiting for
                            > the queue, 3 items in the queue, when the 4th item is added, only 1 thread
                            > will wake up, that single thread will process all the items... I'm not sure
                            > that Jon's code solves the problem, as Monitor.Pulse only releases a single
                            > thread.
                            >[/color]

                            Yep. I suppose that isn't necessarily a problem though. It just
                            depends on what behavior you want. You could use the ManualResetEven t
                            instead which does wake all threads. Jon mentioned that problem in a
                            post recently and he basically said that you could change that behavior
                            in his solution by using PulseAll instead Pulse, but for most scenarios
                            he saw no compelling reason to do so.

                            I was comparing the execution flow with your revised solution and Jon's
                            solution. Functionally, they are very similar. AutoResetEvent. Set and
                            AutoResetEvent. WaitOne appear to have the same semantics as
                            Monitor.Pulse and Monitor.Wait. ManualResetEven t.Set and
                            ManualResetEven t.WaitOne appear to have the same semantics as
                            Monitor.PulseAl l and Monitor.Wait.

                            Comment

                            Working...