TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #1638 1.39K
День 1320. #ЗаметкиНаПолях #AsyncTips
Асинхронные интерфейсы и наследование

Задача:
В интерфейсе или базовом классе имеется метод, который требуется сделать асинхронным.

Решение
Ключом к пониманию этой задачи и её решения станет понимание того, что async относится к подробностям реализации. Ключевое слово async может применяться только к методам с реализациями. Невозможно применить его к абстрактным методам или методам интерфейсов (если они не имеют реализации по умолчанию). Тем не менее вы можете определить метод с такой же сигнатурой, как у async-метода, но без ключевого слова async.

Ожидание допускают типы, а не методы. Вы можете использовать await с объектом Task, возвращённым методом, независимо от того, был метод реализован с ключевым словом async или нет. Таким образом, интерфейс или абстрактный метод может просто вернуть Task (или Task<T>), и это значение может ожидаться.

Следующий пример определяет интерфейс с асинхронным методом (без ключевого слова async), реализацию этого интерфейса (с async), и независимый метод, который потребляет метод этого интерфейса (посредством await):
interface ICountBytes
{
Task<int> CountBytesAsync(
HttpClient hc, string url);
}

class Counter : ICountBytes
{
public async Task<int>
CountBytesAsync(HttpClient hc, string url)
{
var b = await hc.GetByteArrayAsync(url);
return b.Length;
}
}
…
async Task UseCounter(
HttpClient hc,
ICountBytes svc)
{
var res = await svc.CountBytesAsync(
hc,
"http://www.google.com");

Console.WriteLine(res);
}

Этот паттерн работает и с абстрактными методами базовых классов.
Асинхронная сигнатура метода (возврат Task или Task<T>) означает лишь то, что реализация может быть асинхронной. Фактическая реализация может быть синхронной, если нет реальной асинхронной работы, которую нужно было бы выполнять. Например, тестовая заглушка может реализовать тот же интерфейс (без async), используя, например, FromResult:
class CounterStub : ICountBytes
{
public Task<int> CountBytesAsync(
HttpClient hc, string url)
{
return Task.FromResult(13);
}
}

Асинхронные методы интерфейсов и базовых классов встречаются всё чаще. Работать с ними не так уж сложно, если помнить, что ожидание должно применяться к возвращаемому типу (а не к методу), а определение асинхронного метода может быть реализовано как асинхронно, так и синхронно.

См. также: Возвращение завершённых задач

Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 11.
  • 👍 7
More from @netdeveloperdiary
  1. Oct 14, 2026Post #3373
  2. Oct 13, 2026День 2813. #ЗаметкиНаПолях #Async Ещё Раз Про Async/Await в C#. Часть 1 1. Почему существу…
  3. Oct 12, 2026День 2812. #Карьера #AI Как Разработчикам Оставаться Полезными, Когда Код Пишет ИИ? По мер…
  4. Oct 11, 2026День 2811. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  5. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  6. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →