Так же как ключевое слово await может использовать любой асинхронный метод, который соответствует определенному шаблону (см. далее), C# предлагает такую же гибкость в применении к реализации асинхронного метода. Вы не ограничены Task, Task, ValueTask и ValueTask. Вы можете вернуть любой тип, который удовлетворяет двум условиям: он должен быть аннотирован атрибутом AsyncMethodBuilder, определяющим класс, который компилятор может использовать для управления ходом выполнения и завершением задачи, а также содержать метод GetAwaiter, который возвращает тип, реализующий интерфейс ICriticalNotifyCompletion.