We left Russia. We are against aggression and war with Ukraine. It is a tragedy for our nations, it is a nightmare

Use of AsyncLocal<T> in a job

Hi,
in a job I need to use an AyncLocal to store and retrieve values across threads.
I expect the value of my static AsyncLocal to be “default” when the job starts, but unfortunately it holds the value of the last job executed on the same thread (JobWorker).

follow small example:

public class MyJobClass
{
	static AsyncLocal<string> MyValue = new AsyncLocal<string>();
	
	public void MyJob(string value)
	{
		if (MyValue.Value != default(string))
			Console.WriteLine("ERROR! MyValue isn't supposed to hold a value at this point");
		Console.WriteLine(MyValue.Value);
		MyValue.Value = value;
		
	}
}

I believe this happens because when the jobserver starts a new job, it doesn’t suppress the execution flow, see: ExecutionContext.SuppressFlow Method (System.Threading) | Microsoft Learn

Thus the variable holds the value left from the last job executed within the same thread, making that variable unusable.
Please consider that the class above is an over simplified proof of concept, in the application the value of the asyncLocal is used from services that I don’t have control of.

I’m afraid Execution.SuppressFlow doesn’t help there as nothing is changed here when calling the following code instead:

public static void AsyncLocalJob(string value)
{
    using (ExecutionContext.SuppressFlow())
    {
        Console.WriteLine("Starting AsyncLocalJob");
        if (MyValue.Value != default(string))
            Console.WriteLine("ERROR! MyValue isn't supposed to hold a value at this point");
        Console.WriteLine(MyValue.Value);
        MyValue.Value = value;
    }
}
Starting AsyncLocalJob

Starting AsyncLocalJob
ERROR! MyValue isn't supposed to hold a value at this point
hello

However if we are using async Task signature instead, all is working as expected:

public async Task MyJob(string value)
{
	if (MyValue.Value != default(string))
		Console.WriteLine("ERROR! MyValue isn't supposed to hold a value at this point");
	Console.WriteLine(MyValue.Value);
	MyValue.Value = value;
}

And the output is the following one:

Starting AsyncLocalJob

Starting AsyncLocalJob

Tried this on both .NET Core (5.0) and .NET Framework.