12

How can I wait for n number of pulses?

… // do something
waiter.WaitForNotifications();

I want the above thread to wait until being notified n times (by n different threads or n times by the same thread).

I believe there is a type of counter to do this, but I can't find it.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
Toto
  • 7,491
  • 18
  • 50
  • 72

2 Answers2

22

Have a look at the CountdownEvent Class:

CountdownEvent Class

Represents a synchronization primitive that is signaled when its count reaches zero.

Example:

CountdownEvent waiter = new CountdownEvent(n);

// notifying thread
waiter.Signal();

// waiting thread
waiter.Wait();
Community
  • 1
  • 1
dtb
  • 213,145
  • 36
  • 401
  • 431
8

By using a simple ManualResetEvent and Interlocked.Decrement

class SimpleCountdown
{
    private readonly ManualResetEvent mre = new ManualResetEvent(false);

    private int remainingPulses;

    public int RemainingPulses
    {
        get
        {
            // Note that this value could be not "correct"
            // You would need to do a 
            // Thread.VolatileRead(ref this.remainingPulses);
            return this.remainingPulses;
        }
    }

    public SimpleCountdown(int pulses)
    {
        this.remainingPulses = pulses;
    }

    public void Wait()
    {
        this.mre.WaitOne();
    }

    public bool Pulse()
    {
        if (Interlocked.Decrement(ref this.remainingPulses) == 0)
        {
            mre.Set();
            return true;
        }

        return false;
    }
}

public static SimpleCountdown sc = new SimpleCountdown(10);

public static void Waiter()
{
    sc.Wait();
    Console.WriteLine("Finished waiting");
}

public static void Main()
{
    new Thread(Waiter).Start();

    while (true)
    {
        // Press 10 keys
        Console.ReadKey();

        sc.Pulse();
    }
}

Note that in the end, this your problem is often connected to this other problem: Workaround for the WaitHandle.WaitAll 64 handle limit?

My solution is good if you don't have .NET >= 4 (because the other solution, CountdownEvent, was introduced in .NET 4)

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280