gpt4 book ai didi

c# - 调用链中的异步等待分配

转载 作者:行者123 更新时间:2023-11-30 19:53:11 25 4
gpt4 key购买 nike

我试图更好地理解由于编译器为 C# 中的异步等待生成代码而发生的堆分配。

考虑以下代码:

static async Task OneAsync()
{
Console.WriteLine("OneAsync: Start");
await TwoAsync();
Console.WriteLine("OneAsync: End");
}

static async Task TwoAsync()
{
Console.WriteLine("TwoAsync: Start");
await ThreeAsync();
Console.WriteLine("TwoAsync: End");
}

static async Task ThreeAsync()
{
Console.WriteLine("ThreeAsync: Start");
var c = new HttpClient();
var content = await c.GetStringAsync("http://google.com");
Console.WriteLine("Content:" + content.Substring(0, 10));
Console.WriteLine("ThreeAsync: End");
}

来自 ILSpy From ILSpy

这里我们有 3 种 AsyncStateMachine 结构类型(一种用于 OneAsync,一种用于 TwoAsync,一种用于 ThreeAsync) 由编译器生成。

能否请您确认我的假设是否正确?

  • 调用 OneAsync 方法(依次调用链,直到 ThreeAsync),将导致 3 AsyncStateMachine struct types 要放在上?

  • 如果我没有在 ThreeAsync 方法中使用 HttpClient 而只是从它返回 Task.CompletedTask,那么会有 2 个 AsyncStateMachine 结构类型(一种用于 OneAsync,一种用于 TwoAsync)。在这种情况下,不会为 AsyncStateMachine 结构类型分配堆,因为整个调用链会同步执行吗?

最佳答案

无论哪种方式,您都会有三个状态机,因为存在三个异步方法。编译器创建的 stub 总是创建一个状态机。如果您将 ThreeAsync 更改为没有 async 修饰符,而是只编写一个返回已完成任务的常规 方法,您将有两个.

关于堆分配,您是对的:所涉及的等待者在检查时都已完成,因此不需要安排继续。这意味着除了(可能)任务之外,不需要堆分配任何东西。当您返回纯 Task 并且任务总是成功时,我希望也使用缓存的已完成任务。

关于c# - 调用链中的异步等待分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50412177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com