考虑以下代码:
private static async Task Main(string[] args)
{
await SetValueInAsyncMethod();
PrintValue();
await SetValueInNonAsyncMethod();
PrintValue();
}
private static readonly AsyncLocal<int> asyncLocal = new AsyncLocal<int>();
private static void PrintValue([CallerMemberName] string callingMemberName = "")
{
Console.WriteLine($"{callingMemberName}: {asyncLocal.Value}");
}
private static async Task SetValueInAsyncMethod()
{
asyncLocal.Value = 1;
PrintValue();
await Task.CompletedTask;
}
private static Task SetValueInNonAsyncMethod()
{
asyncLocal.Value = 2;
PrintValue();
return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
如果在.NET 4.7.2控制台应用程序中运行此代码,则将获得以下输出:
SetValueInAsyncMethod: 1
Main: 0
SetValueInNonAsyncMethod: 2
Main: 2
Run Code Online (Sandbox Code Playgroud)
我确实知道,输出的差异是由以下事实引起的:该事实实际上SetValueInAsyncMethod不是方法,而是由状态机执行的,AsyncTaskMethodBuilder该状态机在ExecutionContext内部捕获并且SetValueInNonAsyncMethod只是常规方法。
但是即使有了这种理解,我仍然有一些问题: …
我使用与HttpContextAccessor类似的模式
简化版如下,Console.WriteLine(SimpleStringHolder.StringValue)不应该是null。
public class SimpleStringHolder
{
private static readonly AsyncLocal<ValueHolder> CurrentHolder = new AsyncLocal<ValueHolder>();
public static string StringValue
{
get => CurrentHolder.Value?.StringValue;
set
{
var holder = CurrentHolder.Value;
if (holder != null)
{
holder.StringValue = null;
}
if (value != null)
{
CurrentHolder.Value = new ValueHolder() { StringValue = value };
}
}
}
private class ValueHolder
{
public string StringValue;
}
}
Run Code Online (Sandbox Code Playgroud)
class Program
{
private static readonly AsyncLocal<string> currentValue = new AsyncLocal<string>();
public static …Run Code Online (Sandbox Code Playgroud)