using System.Threading;

SemaphoreSlim semA = new SemaphoreSlim(0);
SemaphoreSlim semB = new SemaphoreSlim(0);

private void ThreadA() {
    Console.WriteLine("[ThreadA] doing some work");
    Thread.Sleep(400);

    Console.WriteLine("[ThreadA] Synchronising with ThreadB");
    semB.Wait();
    semA.Release();

    Console.WriteLine("[ThreadA] continue with work");
}

private void ThreadB() {
    Console.WriteLine("[ThreadB] doing some work");
    Thread.Sleep(300);

    Console.WriteLine("[ThreadB] Synchronising with ThreadA");
    semA.Wait();
    semB.Release();

    Console.WriteLine("[ThreadB] continue with work");
}


var t1 = new Thread(() => ThreadA());
var t2 = new Thread(() => ThreadB());
t1.Start();
t2.Start();