为什么在调用Test()时,对data.Value
的更改没有被反映到Main方法中?即使Test方法上没有await
,这意味着它将被同步执行。
public class Data {
public Data data;
public int count;
}
public class Program {
public static AsyncLocal<Data> data = new();
public static async Task Main(string[] args){
data.Value = new Data{
data = new Data{ count = 5 },
count = 10
};
Console.WriteLine($"[Main] - Data = {data?.Value?.GetHashCode()}, Data Count = {data?.Value?.count}, " +
$"SubData Count = {data?.Value?.data?.count},\n ThreadId = {Thread.CurrentThread.ExecutionContext!.GetHashCode()}");
Console.WriteLine($"[Main] - AsyncLocal HashCode = {data.GetHashCode()}");
var task = Test();
Console.WriteLine($"[Main] - Data = {data?.Value?.GetHashCode()}, Data Count = {data?.Value?.count}, " +
$"SubData Count = {data?.Value?.data?.count},\n ThreadId = {Thread.CurrentThread.ExecutionContext.GetHashCode()}");
Console.WriteLine($"[Main] - AsyncLocal HashCode = {data.GetHashCode()}");
await task;
}
private static async Task Test()
{
data.Value = new Data{
data = new Data{ count = 15 },
count = 20
};
Console.WriteLine($"Data = {data.GetHashCode()}, Data Count = {data?.Value?.count}, SubData Count = {data?.Value?.data?.count}, " +
$"\n ThreadId = {Thread.CurrentThread.ExecutionContext.GetHashCode()}");
Console.WriteLine($"AsyncLocal HashCode = {data.GetHashCode()}");
}
}
[Main] - Data = 58225482,Data Count = 10,SubData Count = 5,ThreadId = 54267293 [Main] - AsyncLocal HashCode = 18643596
Data = 18643596,Data Count = 20,SubData Count = 15,ThreadId = 33574638 AsyncLocal HashCode = 18643596
[Main] - Data = 58225482,Data Count = 10,SubData Count = 5,ThreadId = 54267293 [Main] - AsyncLocal HashCode = 18643596
1条答案
按热度按时间68bkxrlz1#
为什么调用Test()时,data.Value的更改没有反映到Main方法中?
每个
async
方法获取执行上下文的 * 副本 *,其中包括AsyncLocal<T>
值。换句话说,AsyncLocal<T>
值不会“向上”流动。从技术上讲,它们可以从非
async
方法“向上”流动,但我强烈建议不要依赖于这种行为;它很奇怪,如果任何中间方法从sync更改为async,它很容易被破坏。即使Test方法上没有await,这意味着它将同步执行。
async
关键字(或者从技术上讲,async
关键字生成的状态机)捕获上下文。Test
同步执行,因为没有await
;但是由于async
关键字的原因,有一个副本。由于修改只发生在副本上,所以它无论如何都会丢失,即使Test
同步执行。