gpt4 book ai didi

c# - ValueTask 和异步状态机

转载 作者:太空狗 更新时间:2023-10-29 23:49:00 24 4
gpt4 key购买 nike

根据documentation ValueTask<TResult> ...

Provides a value type that wraps a Task<TResult> and a TResult, only one of which is used.

我的问题是关于 C# 编译器在遇到 async 关键字时生成的状态机。当结果立即可用时生成包装 ValueTask<TResult>TResult 或当结果在 Task<TResult> 之后生成包装 awaitGetNowAsync(false) 是否足够聪明?这是一个例子:

static async ValueTask<DateTime> GetNowAsync(bool withDelay)
{
if (withDelay) await Task.Delay(1000);
return DateTime.Now;
}

static void Test()
{
var t1 = GetNowAsync(false);
var t2 = GetNowAsync(true);
}

调用 TResult 应该返回一个 GetNowAsync(true) 包装器,因为没有等待任何东西,而调用 Task<TResult> 应该返回一个 Task.Delay 包装器,因为在结果可用之前等待 Task。我担心状态机总是返回 ValueTask 包装器的可能性,从而抵消了 Task 类型相对于 ValueTask<TResult> 的所有优点(并保留了所有缺点)。据我所知,ojit_code 类型的属性没有提供关于它内部包装的内容的指示。我将上面的代码粘贴到 sharplab.io ,但输出也没有帮助我回答这个问题。

最佳答案

我想我应该回答我自己的问题,因为我现在知道答案了。答案是我的担心是没有根据的:C# 编译器足够聪明 可以生成正确类型的 ValueTask<TResult>。在任何情况下。当结果同步可用时,它会发出一个值包装器,否则会发出一个任务包装器。

我通过性能测量得出这个结论:通过测量每种情况下分配的内存,以及创建相同数量的任务所需的时间。结果清晰且一致。例如 ValueTask<int>当它包装 int 时正好消耗 12 个字节值,当它包装一个 Task<int> 时正好是 48 个字节,所以毫无疑问,引擎盖下发生了什么。

关于c# - ValueTask<TResult> 和异步状态机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57440047/

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