Проблем с async/await при връзката между слоевете в ASP.NET Web API ?

+6 гласа
35 прегледа
попитан 2016 април 1 в .NET от Viktor.Ivanov. (1,550 точки)

Попаднах на малък проблем. Написах ASP.NET Web API и автоматично добавих async на контролера и сега,разбира се, изисква да използвам и await.

Проблемът е, че контролерът е свързан със service слоя, а този слой се свързва с data слоя.Data слоя е този, който извиква асинхронната версия на GET, за да направи асинхронно извикване на друга REST услуга- това е лесно, мога да направя метода от data слоя да има async и ще сложа await на извикването на HttpClient GetSync.

Но за да поддържа async/await service слоя, трябва да променя типа, който връща на Task. Но service слоя не прави нищо асинхронно. Той извиква data слоя, който всъщност извиква асинхронните методи на HttpClient.

Имам 2 възможности, имайки предвид ,че имам следната структура на слоевете:

ASP.NET Web Api >> Service Layer >> Data Layer

-Да използвам async/await само в data слоя.

-Или да сложа async/await в контролера и метода от service слоя. Това изисква рефакториране,за да променя типа,който връща на Task

Предполагам, че не го разбирам напълно.Предвид, че единствените блокиращи извиквания ще са в data слоя, за да се върнат всички нишки в thread pool-а трябва само да сложа async/await в data слоя?

Тогава трябва ли да използвам шаблони за контролерите?

1 отговор

+1 глас
отговорени 2016 април 2 от valeri.hristov (7,340 точки)
избран 2016 април 11 от Mitko Vasilev
 
Най-добър отговор

 автоматично добавих async на контролера и сега,разбира се, изисква да използвам и await.

Правиш нещата наобратно. Трябва да слагаш async на метод,само ако имаш нужда от await.

Да използвам async/await само в data слоя.

Не трябва да слагаш асинхронни методи в синхронни API-та. Това важи особено за сървърен код, защото в такъв случай губиш ползите от async.

 Или да сложа async/await в контролера и метода от service слоя. Това изисква рефакториране,за да променя типа,който връща на Task

Това е правилния подход. Ето ти насоки, които да следваш:

  1. Не блокирай async кода. Не извиквай Task.Wait или  Task<T>.Result. Това може да доведе до deadlock. Дори и да го подкараш да работи, все пак губиш ползите от async от страна на сървъра.
  2. Избягвай async void. Особено на сървъра.
  3. Вместо Wait или Result, използвай await. Това означава, че изчакващият метод ще трябва да бъде async Task или async Task<T>, което значи, че методите които го извикват също ще трябва да изчакват. Така async се „пренася“ в кода. Това е нормално и правилно.

Може също да погледнеш следната статия за добрите практики в асинхронното програмиране:

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

...