. Net Core: nvalidOperationException: была предпринята попытка использовать контекст во время его настройки. - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь запустить 6 задач параллельно и периодически получаю эту ошибку:

InvalidOperationException: была сделана попытка использовать контекст во время его настройки. Экземпляр DbContext нельзя использовать внутри OnConfiguring, поскольку он все еще настраивается на этом этапе. Это может произойти, если вторая операция запускается в этом контексте до завершения предыдущей операции. Любые члены экземпляра не гарантированно являются потокобезопасными. Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider ()

StartUp.cs

services.AddDbContext<myDbContext>(options => options.UseSqlServer(_config.GetConnectionString("DefaultConnection")));

Службы, которые я использую для текущих задач:

services.AddScoped<IPostService, PostService>();
services.AddScoped<IPartnerService, PartnerService>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IRelatedRepository, RelatedRepository>();
services.AddSingleton<ICookieRepository, CookieRepository>();

Способ, которым я пытаюсь выполнить свои задачи и получить исключение:

         var relatedTipsTask = Task.Run(() => GetRelatedTipsVms(citiesIDs, countriesIDs, categoriesIDs, bigNumToTake, tipID));

        ////#1.2 Get related texts widgets
        var relatedTextsTask = Task.Run(() => GetRelatedTextsVms(citiesIDs, countriesIDs, categoriesIDs, smallNumToTake, textID));

        ////#1.3 Get related partners widgets
        var relatedPartnersTask = Task.Run(() => GetRelatedPartnersVms(smallNumToTake, partnerID));

        ////#1.4 Get related post widgets
        var relatedPostsTask = Task.Run(() => GetRelatedPostsVms(citiesIDs, countriesIDs, smallNumToTake, postID));

        ////#1.5 Get related businesses
        var relatedBusinessesTask = Task.Run(() => GetRelatedBusinessVms(citiesIDs, countriesIDs, smallNumToTake, businessID));

        ////#1.6 Get related preflight
        var relatedPreflightTask = Task.Run(() => GetRelatedPreflightVms(bigNumToTake, textID));

        await Task.WhenAll(relatedTipsTask, relatedTextsTask, relatedPartnersTask, relatedPostsTask, relatedBusinessesTask, relatedPreflightTask);

Второй вопрос, когда я запускаю его так, он работает нормально, но syn c (не asyn c), почему это?

        //#1.1 Get related tips widgets
        var relatedTipsTask = GetRelatedTipsVms(citiesIDs, countriesIDs, categoriesIDs, bigNumToTake, tipID);

        //#1.2 Get related texts widgets
        var relatedTextsTask = GetRelatedTextsVms(citiesIDs, countriesIDs, categoriesIDs, smallNumToTake, textID);

        //#1.3 Get related partners widgets
        var relatedPartnersTask = GetRelatedPartnersVms(smallNumToTake, partnerID);

        //#1.4 Get related post widgets
        var relatedPostsTask = GetRelatedPostsVms(citiesIDs, countriesIDs, smallNumToTake, postID);

        //#1.5 Get related businesses
        var relatedBusinessesTask = GetRelatedBusinessVms(citiesIDs, countriesIDs, smallNumToTake, businessID);

        //#1.6 Get related preflight
        var relatedPreflightTask = GetRelatedPreflightVms(bigNumToTake, textID);
        await Task.WhenAll(relatedTipsTask, relatedTextsTask, relatedPartnersTask, relatedPostsTask, relatedBusinessesTask, relatedPreflightTask);

1 Ответ

2 голосов
/ 23 марта 2020

То, что вы сделали, было явным нарушением того, что указано в документе Microsoft c. о Entity Framework Core.

Entity Framework Core не поддерживает несколько параллельных операций, выполняемых на одном экземпляре DbContext

https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

Основное различие между вашими двумя стилями выполнения, приведенными выше, заключается в том, что первый из них заставляет несколько потоков использовать контекст БД. Я бы предложил вам сделать репо. методы. асинхронный (EF Core имеет встроенные методы asyn c.) и позволяет инфраструктуре управлять ресурсами вместо использования Task.Run для выполнения задач ввода-вывода.

Кроме того, практическое правило Task. Выполнить для задачи, связанной с процессором, тогда как async / await для задачи, связанной с вводом / выводом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...