public static async Task NotifyOnThreadContextChange()
{
bool expectThreadContextChange = false;
int expectedPreviousValue = 0;
int expectedCurrentValue = 1;
bool gotNotification = false;
bool expectNotification = false;
AsyncLocal<int> local = new AsyncLocal<int>(
args =>
{
gotNotification = true;
Assert.True(expectNotification);
expectNotification = false;
Assert.Equal(args.ThreadContextChanged, expectThreadContextChange);
Assert.Equal(args.PreviousValue, expectedPreviousValue);
Assert.Equal(args.CurrentValue, expectedCurrentValue);
});
expectNotification = true;
local.Value = 1;
Assert.True(gotNotification);
gotNotification = false;
ExecutionContext ec = ExecutionContext.Capture();
expectNotification = true;
expectedPreviousValue = 1;
expectedCurrentValue = 2;
local.Value = 2;
Assert.True(gotNotification);
gotNotification = false;
expectNotification = true;
expectedPreviousValue = 2;
expectedCurrentValue = 1;
expectThreadContextChange = true;
ExecutionContext.Run(
ec,
_ =>
{
Assert.True(gotNotification);
gotNotification = false;
Assert.Equal(local.Value, 1);
expectNotification = true;
expectedPreviousValue = 1;
expectedCurrentValue = 3;
expectThreadContextChange = false;
local.Value = 3;
Assert.True(gotNotification);
gotNotification = false;
expectNotification = true;
expectedPreviousValue = 3;
expectedCurrentValue = 2;
expectThreadContextChange = true;
return;
},
null);
Assert.True(gotNotification);
gotNotification = false;
Assert.Equal(local.Value, 2);
expectNotification = true;
expectThreadContextChange = true;
expectedPreviousValue = local.Value;
expectedCurrentValue = 0;
return;
}