Skip to content

Instantly share code, notes, and snippets.

@Mohsens22
Created May 16, 2024 14:43
Show Gist options
  • Select an option

  • Save Mohsens22/a495a29aabc809e8e67bb5c4a4997901 to your computer and use it in GitHub Desktop.

Select an option

Save Mohsens22/a495a29aabc809e8e67bb5c4a4997901 to your computer and use it in GitHub Desktop.
This gist tests if Task.Run and Parallel.ForEachAsync actually create async contexts.
namespace PatchUpYaml.Tasks
{
internal class TestAsyncLocal
{
public async Task ExecuteAsync()
{
var values = Enumerable.Range(0, 16).ToArray();
var tasks = new Task[values.Length];
var asyncLocal = new AsyncLocal<string>();
string notAsyncLocal = "";
foreach (var id in values)
{
tasks[id] = Task.Run(async () =>
{
if (!string.IsNullOrEmpty(asyncLocal.Value))
{
throw new Exception();
}
asyncLocal.Value = "Task " + id;
notAsyncLocal = "Task " + id;
await Task.Delay(100 - (id * 5)); // Simulate some asynchronous operation
Console.WriteLine($"Task {id} - AsyncLocal value: {asyncLocal.Value}, not async {notAsyncLocal}");
});
}
Console.WriteLine("==============");
await Task.WhenAll(tasks);
await Task.Delay(200);
await Parallel.ForEachAsync(values,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
async (id, token) =>
{
if (!string.IsNullOrEmpty(asyncLocal.Value))
{
throw new Exception();
}
asyncLocal.Value = "Task " + id;
notAsyncLocal = "Task " + id;
await Task.Delay(100 - (id * 5)); // Simulate some asynchronous operation
Console.WriteLine($"TaskForeach {id} - AsyncLocal value: {asyncLocal.Value}, not async {notAsyncLocal}");
});
Console.WriteLine("==============");
foreach (var id in values)
{
await Task.Run(async () =>
{
if (!string.IsNullOrEmpty(asyncLocal.Value))
{
throw new Exception();
}
asyncLocal.Value = "Task " + id;
notAsyncLocal = "Task " + id;
await Task.Delay(100 - (id * 5)); // Simulate some asynchronous operation
Console.WriteLine($"Task {id} - AsyncLocal value: {asyncLocal.Value}, not async {notAsyncLocal}");
});
}
Console.WriteLine("==============");
foreach (var id in values)
{
if (!string.IsNullOrEmpty(asyncLocal.Value))
{
// Collision WILL happen
Console.WriteLine("Colliosion happened");
}
asyncLocal.Value = "Task " + id;
notAsyncLocal = "Task " + id;
await Task.Delay(100 - (id * 5)); // Simulate some asynchronous operation
Console.WriteLine($"Task {id} - AsyncLocal value: {asyncLocal.Value}, not async {notAsyncLocal}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment