/ / написання методів сховища async всередині мого веб-додатку asp.net mvc5 - asp.net-mvc, asynchronous, asp.net-mvc-5, async-wait, entre-Framework-6

Написання методів репозиторію асинхрон у моєму веб-застосунку asp.net mvc5 - asp.net-mvc, asynchronous, asp.net-mvc-5, async-wait, entity-framework-6

Я працюю на асп.net web-додаток mvc5 + Entity Framework 6. і я хочу мати клас моделі репозиторію всередині моєї програми. в даний час я дотримуюсь цього підходу, щоб мати методи асинхронних дій та клас моделі репозиторію async.

наприклад, у мене є такий метод збереження сховища: -

public class Repository
{

private Entities t = newEntities();

public async Task Save()
{
await t.SaveChangesAsync();
}

що я закликаю до своїх методів дії наступним чином:

Repository repository = new Repository();
public async Task<ActionResult> GetResourceByName(string resourcename)
{
await  repository.Save();
}

так це правильний підхід? як я роблю наступне:

  1. я визначаю метод сховища як завдання, а також метод дії як завдання. тож я повинен мати їх обох як завдань.

  2. я використовую await двічі на метод дії (при виклику методу repo) та на сховище? так це і є await зайве?

// Зверніть увагу, що це лише простий прикладметоду репозиторію, який просто використовується для збереження моделі ,, але я запитую про сам підхід, оскільки я буду використовувати цей підхід у більш складних методах репозиторію ..

Відповіді:

2 для відповіді № 1
  1. Q1: Так, обидва повинні повернути Завдання, і ось так воно має бути, і це повністю добре.
  2. Q2: Так, обидва повинні мати функцію очікування (якщо у вас більше шарів, то всі ці виклики функцій у всіх цих шарах повинні були чекати).

В основному: Після того, як ви перейдете на асинхронізацію / очікування, весь ланцюжок викликів повинен бути асинхронізований / очікувати, щоб уникнути проблем, пов'язаних з потоком ...

Якщо ви не чекаєте, то це називається: "Пожежа та забудьте", що не рекомендується, оскільки тоді цей запит буде повернуто користувачеві з повідомленням про успіх, але пізніше виклик, який ви здійснили без очікування, може не вдатися і викинути виняток, і ви не матимете ідеї з чого це виняток ...


2 для відповіді № 2

Всупереч обом відповідям дві awaits не потрібні. await і async необхідні лише в тому випадку, якщо вам потрібен результат з а Task перш ніж продовжувати. Якщо вам не потрібен цей результат, то вам не потрібно маркувати свій метод async.

Це означає, що цей метод ...

public async Task Save()
{
await t.SaveChangesAsync();
}

Можна спростити в

public Task Save()
{
return t.SaveChangesAsync();
}

Незважаючи на те, що вони функціонально однакові, мені подобається друга версія, тому що вона демонструє це визнання Task - це асинхронна робота, і асинхронізація / очікування - лише сигнали компілятору, щоб дочекатися завершення цієї роботи.


1 для відповіді № 3

Незалежно від інших відповідей, ось чому ви повинні використовувати await і більше.

ASP.NET має контекст синхронізації, який буде захоплено на кожному await та продовження (решта async метод) буде розміщено для цього контексту. Це означає не тільки комутацію потоків, але заповнення переключеного на потік контекстом ASP.NET.

Якщо ви суфіксуєте свої асинхронні дзвінки (ті, що мають await з закликом до ConfigureAwait(false) контекстна комутація ASP.NET не відбудеться (хоча комутація потоку буде).

Оскільки двигун перегляду дій, швидше за все, потребує контексту ASP.NET, ви не можете використовувати його ConfigureAwait(false) про метод дії MVC. Але вам слід скористатися всіма методами, які ним називаються.

Отже, ваш код повинен бути приблизно таким:

public class Repository
{
private Entities t = new Entities();
public async Task SaveAsync()
{
await t.SaveChangesAsync().ConfigureAwait(false);
}
}


Repository repository = new Repository();
public async Task<ActionResult> GetResourceByName(string resourcename)
{
await repository.SaveAsync();
}

Тому що у вас може не бути контексту ASP.NET після await з закликом до ConfigureAwait(false) Ви повинні передати як аргументи все необхідне з контексту ASP.NET.


0 для відповіді № 4

Щоб відповісти на ваші запитання:

  1. Так, вони повинні обидва повертати завдання.
  2. Так await мати сенс. Ні, вони не є зайвими.

Щоб зрозуміти, чому ти може (не потрібно) потрібно await двічі, я пропоную вам переглянути цю статтю, яка дає досить чіткий приклад того, як і чому це працює:

C # асинхронізація і чекай: навіщо вони нам потрібні?

Якщо ви хочете використовувати сховища та, можливо, захочете скористатися послугами для вашої ділової логіки, я рекомендую вам перевірити цей проект, який легко розширюється та є загальним:

URF - Рамка одиниць роботи та сховищ

Перш ніж розглянути питання про розробку всього з нуля, слід перевірити це. Я дуже люблю цей проект!