从内部等待某些任务的方法返回 ValueTask 是否有任何意义

wiu*_*wiu 5 c# async-await valuetask

我有一个异步方法,看起来大约像这样:

async Task<int> ParseStream()
{
    var a = await reader.ReadInt32();
    var b = await reader.ReadInt32();
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

由于数据已经准备好,因此该方法在大多数情况下都会同步工作。因此,用 ValueTask 替换返回类型以减少分配似乎是个好主意。但这会调用reader.ReadInt32()return Task。

所以问题是:从内部等待某些任务的方法返回 ValueTask 是否有意义?

The*_*ias 4

更改方法的签名以返回 aValueTask而不是Task

async ValueTask<int> ParseStreamAsync()
{
    var a = await reader.ReadInt32Async();
    var b = await reader.ReadInt32Async();
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

...的优点是调用您的方法的调用者将避免对象分配,以防两个调用将reader.ReadInt32Async同步完成。但这可能不是一个很大的优势,因为两次调用reader.ReadInt32Async仍可能各自分配一个Task对象,具体取决于此方法的实现方式。理论上有可能一些常见的Task<Int32>返回值会被缓存,但实际上可能性不大。如果返回值是 ,情况会有所不同Task<bool>,缓存仅有的两个可能值会很便宜。Task<TResult>在引入 s 之前,缓存对象是减少分配的唯一方法ValueTask

因此,通过使用ValueTask而不是,Task您可以合理地预期每次调用时会将对象分配从 3 个减少到 2 个,这不是很令人印象深刻,但也不能忽略不计。