考虑以下代码:
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;
}
如果您在 .NET 4.7.2 控制台应用程序中运行此代码,您将获得以下输出:
SetValueInAsyncMethod: 1
Main: 0
SetValueInNonAsyncMethod: 2
Main: 2
我确实理解输出的差异源于这样一个事实,即SetValueInAsyncMethod它不是真正的方法,而是一个执行的状态机,它在内部AsyncTaskMethodBuilder捕获并且只是一个常规方法。ExecutionContextSetValueInNonAsyncMethod
但即使有了这种理解,我仍然有一些问题:
这是错误/缺失的功能还是有意的设计决定?
在编写依赖于 的代码时,我是否需要担心这种行为AsyncLocal
?比如说,我想编写我的TransactionScope
-wannabe,它通过等待点来传输一些环境数据。AsyncLocal
这里够了吗?
当归结为在整个“逻辑代码流”中保留值时,在 .NET 中是否还有其他替代方法AsyncLocal
和CallContext.LogicalGetData
/ ?CallContext.LogicalSetData
慕尼黑5688855
拉丁的传说
相关分类