在异步代码中优化资源使用的一种方法是使用语法来最大程度地减少堆分配,从而减少垃圾回收的压力并增强整体性能。ValueTask<TResult>
堆分配并不完全是坏事,但是当在堆上分配对象时,它会导致垃圾回收周期,从而降低整体应用程序性能。如果堆分配过多,垃圾回收器可能会导致 GC 暂停。
让我们考虑开发人员常用的一种常见异步模式:
public async Task<string> ReadDataAsync()
{
var data = await ReadFromStreamAsync(_stream);
return ProcessData(data);
}
如果更频繁地调用上述方法,则每个请求都会导致在堆内存上分配一个新实例。随着时间的流逝,它会导致垃圾回收开销增加。Task
通过将返回类型从 更改为 ,我们可以减少堆分配Task<TResult>ValueTask<TResult>
public async ValueTask<string> ReadDataAsync()
{
var data = await ReadFromStreamAsync(_stream);
return ProcessData(data);
}
上述优化有利于高频异步操作或方法,这些操作或方法预计将在相当长的时间内同步完成。
创建另一个名为的类,并添加以下代码片段TaskVsValueTask
public static class TaskVsValueTask
{
public static async Task<string> FetchDataAsync()
{
// Simulate a delay to mimic fetching data
await Task.Delay(1000);
return "Data fetched using Task";
}
public static async ValueTask<string> FetchDataValueTaskAsync()
{
// Simulate a delay to mimic fetching data
await Task.Delay(1000); // Note: Use Task.Delay for the sake of example.
return "Data fetched using ValueTask";
}
}
从 main 方法执行,如下所示
#region Day 20: Task vs. Value Task
static async Task<string> ExecuteDay20()
{
Console.WriteLine("Fetching data with Task...");
string result = await TaskVsValueTask.FetchDataAsync();
Console.WriteLine(result);
Console.WriteLine("Fetching data with ValueTask...");
string resultValueTask = await TaskVsValueTask.FetchDataValueTaskAsync();
Console.WriteLine(resultValueTask);
return "Executed Day 20 successfully..!!";
}
#endregion
控制台输出
Fetching data with Task...
Data fetched using Task
Fetching data with ValueTask...
Data fetched using ValueTask
源代码获取:公众号回复消息【code:55619
】