2

Есть апи обращения к хранилищу, выглядит примерно так:

var storage = await Storages.GetLatest(id);

У него мне нужны файлы - storage.Files.Where(...)

Собственно, как логичнее оформлять апи вида получить файлы по id хранилища и фильтру файлов?

Task<IEnumerable<IFile>> GetFilesAsync(storateId, filter)

или

IEnumerable<IFile> GetFiles(storageId, filter)

Я не понимаю, будет ли тут польза от асинхронного запроса хранилища, если модельку файлов я могу получить только от хранилища, которое ещё надо дождаться?

andreycha
  • 25,167
  • 4
  • 46
  • 82
Monk
  • 4,478

1 Answers1

3

Если внутри вы используете асинхронные методы, то делайте метод API тоже асинхронным, не прячьте асинхронный код за синхронным (т.н. sync over async). Т.о.:

  • вы позволите клиенту получить выгоду от асинхронности
  • клиент возможно избежит дедлока
  • если клиенту понадобится синхронная реализация, он сам ее сделает исходя из своих требований

P.S. По поводу обратной ситуации, async over sync, был дан ответ тут.

UPD

sync over async мы уже тоже обсуждали.

andreycha
  • 25,167
  • 4
  • 46
  • 82
  • Я немного не ферштейн. Когда storage.Files у меня типа IEnumerable<IFile>, будет ли польза вот от такой обертки (http://pastebin.com/tMYCwb5t), условно говоря? – Monk Sep 05 '16 at 15:00
  • @Monk да, будет. Вы же сам storage получаете асинхронно. – andreycha Sep 05 '16 at 15:01
  • Забыл записать в вопросе - надо ли каждую таску обвешивать .ConfigureAwait(false), учитывая, что я пока пишу либу, которая потом будет использоваться где то в интерфейсе? – Monk Sep 05 '16 at 15:03
  • @Monk да, желательно. Иначе если этот код будет вызываться из UI, то практически весь код методов по цепочке вызова будет выполняться в UI-потоке. .ConfigureAwait(false) говорит о том, что контекст захватываться не будет и что продолжение метода будет выполнено в дефолтном контексте (читай, в пуле потоков). Соответственно если в продолжении нет никакой работы с компонентами, требующими конкретный поток (а в библиотечном коде такого по идее не должно быть), то нужно указывать .ConfigureAwait(false). – andreycha Sep 05 '16 at 15:09
  • @Monk Можете так делать - но помните, что это не единственный и не самый лучший способ оптимизации и борьбы с дедлоками (хотя и самый простой). Подробности - по той ссылке, которую вам уже приводили. – Pavel Mayorov Sep 05 '16 at 15:18