Багатоасинхронізація в Entity Framework 6?


87

Це мій код:

var banner = context.Banners.ToListAsync()
var newsGroup = context.NewsGroups.ToListAsync()
await Task.WhenAll(banner, newsGroup);

Але коли я викликав функцію з контролера. Це показало помилку

Друга операція розпочата в цьому контексті до завершення попередньої асинхронної операції. Використовуйте 'await', щоб переконатися, що будь-які асинхронні операції завершені, перш ніж викликати інший метод у цьому контексті. Будь-які члени екземпляра не гарантовано захищають від потоків.

Будь ласка, допоможіть мені вирішити цю проблему.


У мене 2 завдання. Якщо я виконую кожне завдання. це успіх. але якщо я запускаю, як мій код вище. Це помилка
An Hv

Відповіді:


119

Виняток чітко пояснює, що одночасно допускається лише одна асинхронна операція в контексті.

Отже, вам доведеться awaitїх отримувати по черзі, як пропонується в повідомленні про помилку:

var banner = await context.Banners.ToListAsync();
var newsGroup = await context.NewsGroups.ToListAsync();

Або ви можете використовувати кілька контекстів:

var banner = context1.Banners.ToListAsync();
var newsGroup = context2.NewsGroups.ToListAsync();
await Task.WhenAll(banner, newsGroup);

33
просто примітка, якщо у вас є змінна «Ледачий», яка використовує контекст у запиті, навіть із очікуванням, він викличе таку ж помилку, просто отримайте властивість перед запитом, це було боляче з’ясувати це.
Pedro.The.Kid

7
@ Pedro.The.Kid: Як правило, не використовуйте ліниве завантаження з асинхронним доступом до БД. Ледаче завантаження завжди синхронне, тому набагато краще використовувати Включити або окремі запити для додаткових даних.
Стівен Клірі

1
Чи існує якась конкретна причина, чому вам потрібен контекст для асинхронного запиту? Я відчуваю, що це стає досить обмежуючим фактором.
Zapnologica

1
@Zapnologica: Це просто спосіб розробки ES6. Кожен контекст може обробляти лише один запит за раз . Отже, якщо ви закінчите один запит до початку наступного, вам знадобиться лише один контекст. Проблема полягає лише в тому, що ви хочете робити кілька запитів одночасно.
Стівен Клірі,

@StephenCleary, мені важко знайти цей запит, оскільки я не маю нічого безпосередньо перед винятком. Чи є у нас спосіб знайти те, що зараз виконується? Дякую
Фабіо Мілхейро,


3

Якщо ви використовуєте Unity для введення залежностей з, наприклад, шаблоном репозиторію, ви отримаєте таку помилку, використовуючи два або більше контекстів із create / update / delete:

Зв'язок між двома об'єктами неможливо визначити, оскільки вони приєднані до різних об'єктів ObjectContext.

Це можна вирішити за допомогою PerRequestLifetimeManager. Більше інформації тут:

C # EF6 здійснює кілька асинхронних викликів до одного контексту за допомогою Unity - Asp.Net Web Api

container.RegisterType<DbContext>(new PerRequestLifetimeManager());
container.RegisterType<ISupplierRepository, SupplierRepository>();
container.RegisterType<IContactRepository, ContactRepository>();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.