C# solution using AutoResetEvent
Uses three AutoResetEvent objects to synchronize between the three threads.
Uses three AutoResetEvent objects to synchronize between the three threads.

```csharp []
using System.Threading;

public class ZeroEvenOdd {
    private AutoResetEvent _gateZero = new AutoResetEvent(true);
    private AutoResetEvent _gateEven = new AutoResetEvent(false);
    private AutoResetEvent _gateOdd = new AutoResetEvent(false);
    
    private int stop;
    private int current = 0;
    
    public ZeroEvenOdd(int stop) {
        this.stop = stop;
    }

    // printNumber(x) outputs "x", where x is an integer.
    public void Zero(Action<int> printNumber) {
        while (true)
        {
            _gateZero.WaitOne();

            current++;
            if (current <= stop)
            {
                printNumber(0);

                var gate =
                    (current % 2) == 0
                    ? _gateEven
                    : _gateOdd;

                gate.Set();
            }
            else
            {
                _gateEven.Set();
                _gateOdd.Set();

                break;
            }
        }
    }

    public void Even(Action<int> printNumber) {
        while (true)
        {
            _gateEven.WaitOne();

            if (current <= stop)
            {
                printNumber(current);
                _gateZero.Set();
            }
            else
            {
                break;
            }
        }
    }

    public void Odd(Action<int> printNumber) {
        while (true)
        {
            _gateOdd.WaitOne();

            if (current <= stop)
            {
                printNumber(current);
                _gateZero.Set();
            }
            else
            {
                break;
            }
        }
    }
}
```
['Concurrency', 'C#']