Looking for c# Keywords? Try Ask4Keywords

C# Language ValueTask


пример

Task<T> - это класс и вызывает ненужные накладные расходы на его распределение, когда результат сразу доступен.

ValueTask<T> является структурой и был введен для предотвращения выделения объекта Task в случае, если результат операции async уже доступен во время ожидания.

Итак, ValueTask<T> предоставляет два преимущества:

1. Увеличение производительности

Вот пример Task<T> :

  • Требуется распределение кучи
  • Принимает 120 нс с JIT
async Task<int> TestTask(int d)
{
    await Task.Delay(d);
    return 10;
}

Вот ValueTask<T> аналогового значения ValueTask<T> :

  • Нет распределение кучи , если результат известен синхронно (что не в этом случае из-за Task.Delay , но часто не во многих реальных async / await сценариев)
  • Принимает 65ns с JIT
async ValueTask<int> TestValueTask(int d)
{
    await Task.Delay(d);
    return 10;
}

2. Повышенная гибкость внедрения

Реализация асинхронного интерфейса, желающего быть синхронным, в противном случае была бы вынуждена использовать либо Task.Run либо Task.FromResult (что привело к 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;
    }
}

Заметки

Несмотря на то, что в C # 7.0 планировалось добавить конструкцию ValueTask , она пока сохраняется как еще одна библиотека. Пакет ValueTask <T> System.Threading.Tasks.Extensions можно загрузить из галереи Nuget