I noticed that CallContext.LogicalSetData/LogicalGetData
don't work the way I expected them to do. A value set inside an async
method gets restored even when there is no asynchrony or any kind of thread switching, whatsoever.
Here is a simple example:
using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication
{
class Program
{
static async Task<int> TestAsync()
{
CallContext.LogicalSetData("valueX", "dataX");
// commented out on purpose
// await Task.FromResult(0);
Console.WriteLine(CallContext.LogicalGetData("valueX"));
return 42;
}
static void Main(string[] args)
{
using(ExecutionContext.SuppressFlow())
{
CallContext.LogicalSetData("valueX", "dataXX");
Console.WriteLine(CallContext.LogicalGetData("valueX"));
Console.WriteLine(TestAsync().Result);
Console.WriteLine(CallContext.LogicalGetData("valueX"));
}
}
}
}
It produces this output:
dataXX dataX 42 dataXX
If I make TestAsync
non-async, it works as expected:
static Task<int> TestAsync()
{
CallContext.LogicalSetData("valueX", "dataX");
Console.WriteLine(CallContext.LogicalGetData("valueX"));
return Task.FromResult(42);
}
Output:
dataXX dataX 42 dataX
I would understand this behavior if I had some real asynchrony inside TestAsync
, but that's not the case here. I even use ExecutionContext.SuppressFlow
, but that doesn't change anything.
Could someone please explain why it works this way?