Question: I am doing some unit tests and I would like to have a way to have tasks that are already running waiting on given values that the task doing the tests could change at will.

So I have multiple tasks that start running and doing their stuff, then I want to interrupt them midway so that other threads can be at the same stage.
Then check my object is in the expected state, then the thread can run its course.

I know I can do that using a while loop and a boolean, however, I'd like to know if there are better ways to have threads waiting on an update from other threads.

basically, the code would be something along those lines:

```
public void Test() {
    Task.Run(() => {
        // Do Stuff
        // wait the main thread
        // Do Stuff
    })
    Task.Run(() => {
        // Do Stuff
        // wait the main thread
        // Do Stuff
    })

    // Check some stuff
    // signals the tasks to stop waiting
    // Check other stuff
}

```

Thank you for your time.

Answer: 
Based on description sounds like an appropriate place to use [`Barrier`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.barrier?view=net-6.0):

```cs
var barrier = new Barrier(3);

var task1 = Task.Run(() =>
{
    Console.WriteLine("before sync 1");
    barrier.SignalAndWait();
    Console.WriteLine("after sync 1");
});

var task2 = Task.Run(async () =>
{
    await Task.Delay(100);
    Console.WriteLine("before sync 2");
    barrier.SignalAndWait();
    Console.WriteLine("after sync 2");
});

var task3 = Task.Run(async () =>
{
    await Task.Delay(500);
    Console.WriteLine("before sync 3");
    barrier.SignalAndWait();
    Console.WriteLine("after sync 3");
});

await Task.WhenAll(task1, task2, task3);

```

Will print something like:

```
before sync 1
before sync 2
before sync 3
after sync 3
after sync 1
after sync 2

```

But depended on actual use case some other synchronization primitive can be preferable (see [overview of synchronization primitives](https://learn.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitives) and [threading in C# by ​Joseph Albahari](http://www.albahari.com/threading/)).
There is [ManualResetEvent(Slim)](https://learn.microsoft.com/en-us/dotnet/api/system.threading.manualreseteventslim?view=net-6.0) that can be used to provide signaling between threads. These can be used in pairs to get fine grained control over the execution:

```
var signalX= new ManualResetEventSlim(false);
var waitX= new ManualResetEventSlim(false);

var task = new Task.Run(() => {
    // do something
    signalX.Set();
    waitX.Wait();
    // Do something else
});
signalX.Wait();
// Verify state
waitX.Set();

```