Suppose I have these 2 for loops:
Loop a:
for (int i = 0; i < 10; i )
{
Task.Delay(1000)
}
Loop B:
for (int i = 0; i < 10; i )
{
Task.Delay(200)
}
I want to run the loops and loop B should only run after each index of A is complete (The index of B should always be lower than A). When loop B runs, I don't want loop A to pause until loop B is complete. Is there a way to do this?
Note: The Task.Delay is just a placeholder
CodePudding user response:
You can use this quick and dirty SemaphoreSlim
(though not a very correct one) approach (also needs some exception handling and cancelation support):
var sw = Stopwatch.StartNew();
int capacity = 10;
var semaphoreSlim = new SemaphoreSlim(0, capacity);
var t1 = Task.Run(async () =>
{
for (int i = 0; i < capacity; i )
{
await Task.Delay(500);
semaphoreSlim.Release();
}
});
var t2 = Task.Run(async () =>
{
for (int i = 0; i < capacity; i )
{
await semaphoreSlim.WaitAsync();
await Task.Delay(200);
}
});
await Task.WhenAll(t1, t2);
Console.WriteLine(sw.ElapsedMilliseconds);
Or look into some producer-consumer approach like here or using System.Threading.Channels
(again simplified example which lacks error handling and cancelation support):
var sw = Stopwatch.StartNew();
int capacity = 10;
var bounded = Channel.CreateBounded<int>(capacity);
var t1 = Task.Run(async () =>
{
for (int i = 0; i < capacity; i )
{
await Task.Delay(500);
await bounded.Writer.WriteAsync(i);
}
bounded.Writer.Complete();
});
var t2 = Task.Run(async () =>
{
while (await bounded.Reader.WaitToReadAsync())
{
var readAsync = await bounded.Reader.ReadAsync();
await Task.Delay(200);
}
});
await Task.WhenAll(t1, t2);
Console.WriteLine(sw.ElapsedMilliseconds);
CodePudding user response:
An array of Booleans can be used to achieve what you want.
The following would prevent iterations in B from continuing without the iteration for the same indexing in A having been completed.
private const int NoOfIndexes = 100;
private static bool[] IndexesComplete = new bool[NoOfIndexes];
public static void Main()
{
Task.WaitAll(RunLoopA(), RunLoopB());
}
public static async Task RunLoopA()
{
for (int i = 0; i < NoOfIndexes; i )
{
//Main loop work
Console.WriteLine($"A {i}");
//End of main loop work
IndexesComplete[i] = true;
await Task.Delay(50);
}
}
public static async Task RunLoopB()
{
for (int i = 0; i < NoOfIndexes; i )
{
while (!IndexesComplete[i])
{
await Task.Delay(50);
}
//Main loop work
Console.WriteLine($"B {i}");
//End of main loop work
}
}