Согласен, блог Диксин фантастический

из менее обсуждаемых возможностей C # 7 - это «обобщенные типы асинхронного возврата», которые Microsoft описывает как:

Возврат объекта Task из асинхронных методов может привести к появлению узких мест производительности в определенных путях. Задача является ссылочным типом, поэтому его использование означает выделение объекта. В случаях, когда метод, объявленный с модификатором async, возвращает кэшированный результат или завершается синхронно, дополнительные выделения могут стать значительными временными затратами в критически важных для кода разделах кода. Это может стать очень дорогостоящим, если эти распределения происходят в тесных циклах.

Новая функция языка означает, что асинхронные методы могут возвращать другие типы в дополнение кTask, Task<T> а такжеvoid, Возвращаемый тип должен по-прежнему удовлетворять асинхронному шаблону, то есть метод GetAwaiter должен быть доступен. В качестве одного конкретного примера, тип ValueTask был добавлен в .NET Framework для использования этой новой языковой функции:

Это звучит замечательно, но я не могу на всю жизнь найти ни одного примера, который бы не использовал акцииValueTask<T> тип. Я хочу сделать свой собственный тип, похожий на задачу. В частности, я хочу тип, который ведет себя какTask<T>, но с более функциональным стилем обработки ошибок.

Вот тип, который я использую для функциональной обработки ошибок в моем проекте:

public class Try<T> {
    public T Data { get; }
    public Exception Error { get; }

    public bool HasData => Error == null;
    public bool HasError => Error != null;

    public Try(T data) {
        Data = data;
    }

    public Try(Exception error) {
        Error = error;
    }
}

Вот что я думаю должен выглядеть мой пользовательский ожидаемый тип:

public class TryTask<T> : Task<Try<T>> {

    public TryTask(Func<Try<T>> func)
        : base(func) { }

    //GetAwaiter is defined on base type, so we should be okay there
}

Это все компилируется, пока я не попытаюсь использовать его как тип асинхронного возврата:

async TryTask<int> DoWhatever() {
    return await new TryTask<int>(() => new Try<int>(1));
}

Этот метод выдаст ошибку компилятораТип возвращаемого значения асинхронного метода должен быть void, Task или Task.

Как мне сделать это или что-то вроде этого скомпилировать?

Обновить:

Чтобы подтвердить, я использую версию VS 2017 от 3/7, и я могу использовать другие функции C # 7 в моем проекте, такие как локальные функции.

Я также пытался использоватьValueTask и я получаю ту же ошибку компилятора.

static async ValueTask<int> DoWhatever() {
    return await new ValueTask<int&,gt;(1);          
}

Вот еще один пост, который проливает свет на то, что происходит.
Как мне получить новую асинхронную семантику, работающую в VS2017 RC?

По-видимому, необходимо определить отдельный тип «построителя метода» и применить специальные атрибуты к ожидаемому типу. Я не знаю, действительно ли у меня есть время копаться в этом. Это больше похоже на хакерство метапрограммирования, чем на «язык».

Ответы на вопрос(2)

Ваш ответ на вопрос