Search code examples
.netmultithreading.net-3.5synchronizationlocking

How to stop one thread until n threads have completed their work


I have an application with one main thread and N worker threads. At some point I need that the main thread waits until all the N threads have completed one section of their work.

I normally would use Monitor.Wait() and Monitor.Pulse() but this will prevent the N threads from working at the same time.

Any idea on how to do that?

Thanks in advance.


Solution

  • Ok, what I'm doing now (using your ideas) and seems to work is this:

    I declared a list of ManualResetEvent:

    Private m_waitHandles As List(Of Threading.ManualResetEvent)
    

    The process accepts incoming Tcp connections and starts one thread on each connection. So at the new client handler I've added this code:

    Dim waitHandle As Threading.ManualResetEvent
    waitHandle = New Threading.ManualResetEvent(True)
    SyncLock (DirectCast(m_waitHandles, IList).SyncRoot)
        m_waitHandles.Add(waitHandle)
    End SyncLock
    
    ''# Do all the work
    StoppableMethod()
    
    SyncLock (DirectCast(m_waitHandles, IList).SyncRoot)
        waitHandle = m_waitHandles.Item(Threading.WaitHandle.WaitAny(m_waitHandles.ToArray()))
    End SyncLock
    
    waitHandle.Reset()
    NonStoppableMethod()
    waitHandle.Set()
    
    SyncLock (DirectCast(m_waitHandles, IList).SyncRoot)
        m_waitHandles.Remove(waitHandle)
    End SyncLock
    

    The last thing done is to modify the Stop method to be sure that the Stop operation will not done with any thread inside the NonStoppableMethod:

    SyncLock (DirectCast(m_waitHandles, IList).SyncRoot)
        If m_waitHandles.Count > 0 Then
            Threading.WaitHandle.WaitAll(m_waitHandles.ToArray())
        End If
    End SyncLock
    

    I'm not sure that this is done in a right way because it's the first time I deal with things like that. Do you feel that this is ok and is a good approach?

    Thanks to all, mates!