ValueTaskT
Task<T>
是一個類,當結果立即可用時,會導致其分配的不必要開銷。
ValueTask<T>
是一種結構,並且已被引入以防止在等待時非同步操作的結果已經可用的情況下分配 Task
物件。
所以 ValueTask<T>
有兩個好處:
1.效能提升
這是一個 Task<T>
示例:
- 需要堆分配
- 使用 JIT 需要 120ns
async Task<int> TestTask(int d)
{
await Task.Delay(d);
return 10;
}
這是模擬 ValueTask<T>
的例子:
- 如果結果是同步已知的,則沒有堆分配(在這種情況下由於
Task.Delay
而不是,但通常在許多現實世界的async
/await
場景中) - 使用 JIT 需要 65ns
async ValueTask<int> TestValueTask(int d)
{
await Task.Delay(d);
return 10;
}
2.提高實施靈活性
希望同步的非同步介面的實現否則將被迫使用 Task.Run
或 Task.FromResult
(導致上面討論的效能損失)。因此,對同步實現存在一些壓力。
但是使用 ValueTask<T>
,實現可以更自由地在同步或非同步之間進行選擇,而不會影響呼叫者。
例如,這是一個帶有非同步方法的介面:
interface IFoo<T>
{
ValueTask<T> BarAsync();
}
…以下是該方法的呼叫方式:
IFoo<T> thing = getThing();
var x = await thing.BarAsync();
使用 ValueTask
,上面的程式碼將適用於同步或非同步實現 :
同步實施:
class SynchronousFoo<T> : IFoo<T>
{
public ValueTask<T> BarAsync()
{
var value = default(T);
return new ValueTask<T>(value);
}
}
非同步實現
class AsynchronousFoo<T> : IFoo<T>
{
public async ValueTask<T> BarAsync()
{
var value = default(T);
await Task.Delay(1);
return value;
}
}
筆記
雖然計劃將 ValueTask
結構新增到 C#7.0 ,但它暫時保留為另一個庫。 ValueTask <T> System.Threading.Tasks.Extensions
包可以從 Nuget Gallery 下載