Ядро asp.net Вторая операция началась в этом контексте до завершения предыдущей операции - PullRequest
0 голосов
/ 28 мая 2018

У меня есть веб-приложение ASP.Net Core 2.

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

В ConfigureServices Ihave:

services.AddDbContext<DbContext>(options => options.UseMySQL(configuration.GetConnectionString("ConnectionClient")));
services.AddScoped<IServiceConfig, ServiceConfig>();

In Configure:

        app.UseMvc(routes =>
        {
            routes.Routes.Add(new RouteCustom(routes.DefaultHandler);
            routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
        });

In RouteCustom

public class RouteCustom : IRouteCustom
{
    private readonly IRouter _innerRouter;
    private IServiceConfig _serviceConfig;

    public RouteCustom(IRouter innerRouter)
    {
        _innerRouter = innerRouter ?? throw new ArgumentNullException(nameof(innerRouter));
    }

    public async Task RouteAsync(RouteContext context)
    {
        _serviceConfig = context.HttpContext.RequestServices.GetRequiredService<IServiceConfig>();
        ...
        Operations inside _serviceConfig to get the route
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        _serviceConfig = context.HttpContext.RequestServices.GetRequiredService<IServiceConfig>();
        ...
        Operations inside _serviceConfig to get the route
    }
}

IServiceConfig - это просто класс, к которому я обращаюсь к базе данных для получения данныхв этом случае маршруты, а также другие данные конфигурации, которые мне нужны для приложения.

public interface IServiceConfig
{
    Config GetConfig();
    List<RouteWeb> SelRoutesWeb();
}

public class ServiceConfig : IServiceConfig
{
    private readonly IMemoryCache _memoryCache;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IServiceTenant _serviceTenant;

    public ServiceConfig(IMemoryCache memoryCache, IUnitOfWork unitOfWork, IServiceTenant serviceTenant)
    {
        _memoryCache = memoryCache;
        _unitOfWork = unitOfWork;
        _serviceTenant = serviceTenant;
    }


    public Config GetConfig()
    {
        var cacheConfigTenant = Names.CacheConfig + _serviceTenant.GetId();

        var config = _memoryCache.Get<Config>(cacheConfigTenant);
        if (config != null) return config;

        config = _unitOfWork.Config.Get();
        _memoryCache.Set(cacheConfigTenant, config, new MemoryCacheEntryOptions() { SlidingExpiration = Names.CacheExpiration });

        return config;
    }


    public List<RouteWeb> SelRoutesWeb()
    {
        var cacheRoutesWebTenant = Names.CacheRoutesWeb + _serviceTenant.GetId();

        var routesWebList = _memoryCache.Get<List<RouteWeb>>(cacheRoutesWebTenant);
        if (routesWebList != null) return routesWebList;

        routesWebList = _unitOfWork.PageWeb.SelRoutesWeb();
        _memoryCache.Set(cacheRoutesWebTenant, routesWebList, new MemoryCacheEntryOptions() { SlidingExpiration = Names.CacheExpiration });

        return routesWebList;
    }
}

Проблема в том, что я получаю это сообщение, когда я тестирую с несколькими открытыми вкладками и пытаюсь обновить все нав то же время: «Вторая операция началась в этом контексте до завершения предыдущей операции»

Я уверен, что я что-то не так делаю, но я не знаю что.Это должен быть лучший способ доступа к БД в промежуточном программном обеспечении пользовательского маршрута или даже лучший способ сделать это.

Например, на обычном промежуточном программном обеспечении (не на маршрутизации) я могу внедрить зависимости вфункция Invoke, но я не могу вставить здесь зависимости в RouteAsync или GetVirtualPath.

Что здесь может происходить?

Заранее спасибо.

ОБНОВЛЕНИЕ Этоисключения я получаю.Я думаю, что связаны ...

An unhandled exception occurred while processing the request.
InvalidOperationException: A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.

Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider+ExceptionInterceptor+EnumeratorExceptionInterceptor.MoveNext()
System.Collections.Generic.List.AddEnumerable(IEnumerable<T> enumerable)
System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source)
MyProject.Repository.Repositories.PageWebRepository.SelRoutesWeb() in PageWebRepository.cs
+
            return Context.PagesWebTrs.Include(p => p.PageWeb).Where(p => p.PageWeb.Active)
MyProject.Web.AppControl.ServiceConfig.SelRoutesWeb() in ServiceConfig.cs
+
            routesWebList = _unitOfWork.PageWeb.SelRoutesWeb();
MyProject.Web.AppConfig.RouteCustom.GetVirtualPath(VirtualPathContext context) in RouteCustom.cs
+
            var routeWeb = _serviceConfig.SelRoutesWeb().FirstOrDefault(p => p.Area == routeInfo.Area && p.Controller == routeInfo.Controller && p.Action == routeInfo.Action && p.LanguageCode == routeInfo.Culture);
Microsoft.AspNetCore.Routing.RouteCollection.GetVirtualPath(VirtualPathContext context, List<IRouter> routes)
Microsoft.AspNetCore.Routing.RouteCollection.GetVirtualPath(VirtualPathContext context)
Microsoft.AspNetCore.Mvc.Routing.UrlHelper.GetVirtualPathData(string routeName, RouteValueDictionary values)
Microsoft.AspNetCore.Mvc.Routing.UrlHelper.Action(UrlActionContext actionContext)
Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, string action, string controller, object values, string protocol, string host, string fragment)
Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, string action, string controller, object values)
Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateForm(ViewContext viewContext, string actionName, string controllerName, object routeValues, string method, object htmlAttributes)
Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGeneratorExtensions.GenerateForm(IHtmlGenerator generator, ViewContext viewContext, string actionName, string controllerName, string fragment, object routeValues, string method, object htmlAttributes)
Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper.Process(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner+<RunAsync>d__0.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
AspNetCore._Views_Contents_NewsList_cshtml+<ExecuteAsync>d__21.MoveNext() in NewsList.cshtml
+
    <h1>@Model.BasePage.PageTitle</h1>
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderPageCoreAsync>d__16.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderPageAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.Razor.RazorView+<RenderAsync>d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor+<ExecuteAsync>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor+<ExecuteAsync>d__21.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.ViewResult+<ExecuteResultAsync>d__26.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeResultAsync>d__19.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResultFilterAsync>d__24.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyProject.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
            await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()

И этот:

An unhandled exception occurred while processing the request.
MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(Exception exception)

Stack Query Cookies Headers
MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(Exception exception)
MySql.Data.MySqlClient.MySqlCommand.Throw(Exception ex)
MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
System.Data.Common.DbCommand.ExecuteReader()
Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary<string, object> parameterValues)
Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary<string, object> parameterValues)
Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable+Enumerator.BufferlessMoveNext(bool buffer)
Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable+Enumerator.MoveNext()
Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.GetResult<TResult>(IEnumerable<ValueBuffer> valueBuffers, bool throwOnNullResult)
lambda_method(Closure , QueryContext )
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler+<>c__DisplayClass17_1.<CompileQueryCore>b__0(QueryContext qc)
System.Linq.Queryable.Count<TSource>(IQueryable<TSource> source)
X.PagedList.PagedList..ctor(IQueryable<T> superset, int pageNumber, int pageSize)
X.PagedList.PagedListExtensions.ToPagedList<T>(IEnumerable<T> superset, int pageNumber, int pageSize)
MyProject.Repository.Repositories.LinkRepository.SelSearchWeb(string searchText, int pageNumber, int pageSize) in LinkRepository.cs
+
            return Context.LinksTrs.Include(p => p.Link)
MyProject.Web.Controllers.ContentsController.LinksList(LinksSearchModelWeb searchModel) in ContentsController.cs
+
            var items = _unitOfWork.Link.SelSearchWeb(searchModel.SearchText, searchModel.PageNumber ?? 1, searchModel.PageSize ?? 10);
lambda_method(Closure , object , Object[] )
Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(object target, Object[] parameters)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__10.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeInnerFilterAsync>d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
MyProject.Web.AppConfig.TenantMiddleware+<Invoke>d__3.MoveNext() in Tenant.cs
+
            await _next.Invoke(httpContext);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()

Это UnitOfWork

public interface IUnitOfWork : IDisposable
{
    ICompanyRepository Company { get; }
    IConfigRepository Config { get; }
    ...

    void Complete();
}


public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;

    public UnitOfWork(DbContext context)
    {
        _context = context;

        Company = new CompanyRepository(_context);
        Config = new ConfigRepository(_context);
        ...
    }

    public ICompanyRepository Company { get; private set; }
    public IConfigRepository Config { get; private set; }
    ...

    public void Complete()
    {
        _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

ОБНОВЛЕНИЕ

Послепросматривая комментарии и делая много тестов, лучшая подсказка, которую я имею, - когда я удаляю строку CustomRoute, проблема исчезает.Удаление этой строки из функции Configure на Startup.cs

routes.Routes.Add(new RouteCustom(routes.DefaultHandler));

Также я попытался удалить сначала RouteAsync, а затем методы GetVirtualPath, но если один из них присутствует, я получаю сообщение об ошибке, поэтому ясночто проблема в этом классе CustomRoute.

В TenantMiddleware, который вызывается первым для любого запроса, я внедряю UnitOfWork, и у меня нет проблем.Это промежуточное ПО создается в функции Configure:

app.UseMiddleware<TenantMiddleware>();

А внутри я внедряю UnitOfWork и использую его при каждом запросе, например:

public Async Task Invoke (HttpContexthttpContext, IServiceTenant serviceTenant) {... выполнение операций БД для извлечения данных арендатора.

}

public class ServiceTenant : IServiceTenant
{
    public ServiceTenant(IHttpContextAccessor contextAccessor, IMemoryCache memoryCache, IUnitOfWorkMaster unitOfWorkMaster)
    {
        _unitOfWorkMaster = unitOfWorkMaster;
    }

    ...performing DB operations
}

ТАК, проблема с CustomROute заключается в том, что я не могу внедрить зависимости, добавив в функцию Invoke, как это:

public async Task Invoke(HttpContext httpContext, IServiceTenant serviceTenant)

Итак, мне нужно вызвать соответствующую службу (внутри этой службы я внедряю UnitOfWork и выполняю операции с БД) следующим образом, и я думаю, что это может вызывать проблемы:

public async Task RouteAsync(RouteContext context)
{
    _serviceConfig = context.HttpContext.RequestServices.GetRequiredService<IServiceConfig>();
    ....
}

потому что это единственный известный мне способ "вставить" IServiceConfig в RouteAsync и GetVirtualPath ...

Кроме того, я делаю это на каждом контроллере, так как используюBaseCOntroller, поэтому я решаю, какие службы инъекций я использую ...

public class BaseWebController : Controller
{
    private readonly IMemoryCache _memoryCache;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IUnitOfWorkMaster _unitOfWorkMaster;
    private readonly IServiceConfig _serviceConfig;
    private readonly IServiceFiles _serviceFiles;
    private readonly IServiceFilesData _serviceFilesData;
    private readonly IServiceTenant _serviceTenant;

    public BaseWebController(IServiceProvider serviceProvider)
    {
        _memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
        _unitOfWork = serviceProvider.GetRequiredService<IUnitOfWork>();
        _unitOfWorkMaster = serviceProvider.GetRequiredService<IUnitOfWorkMaster>();
        _serviceConfig = serviceProvider.GetRequiredService<IServiceConfig>();
        _serviceFiles = serviceProvider.GetRequiredService<IServiceFiles>();
        _serviceFilesData = serviceProvider.GetRequiredService<IServiceFilesData>();
        _serviceTenant = serviceProvider.GetRequiredService<IServiceTenant>();        }
    ...
}

И затем в каждом контроллере вместо ссылки на всея могу сделать это только для тех, кто мне нужен, например:

public class HomeController : BaseWebController
{
    private readonly IUnitOfWork _unitOfWork;

    public HomeController(IServiceProvider serviceProvider) : base(serviceProvider)
    {
        _unitOfWork = serviceProvider.GetRequiredService<IUnitOfWork>();
    }

    public IActionResult Index()
    {
        ...
    }
}

Я не знаю, связано ли это с моей проблемой, но я просто показываю вам, что ядумаю, это может быть проблемой, поэтому вы можете получить больше информации.

Спасибо.

ОБНОВЛЕНИЕ

Это код базы данных для получения маршрутов:

public class PageWebRepository : Repository<PageWeb>, IPageWebRepository
{
    public PageWebRepository(DbContext context) : base(context) { }


    public List<RouteWeb> SelRoutesWeb()
    {
        return Context.PagesWebTrs.Include(p => p.PageWeb).Where(p => p.PageWeb.Active)
            .Select(p => new RouteWeb
            {
                PageWebId = p.PageWebId,
                LanguageCode = p.LanguageCode,
                Route = p.Route,
                Regex = p.PageWeb.Regex.Replace("<route>", p.Route),
                Params = p.PageWeb.Params,
                Area = p.PageWeb.Area,
                Controller = p.PageWeb.Controller,
                Action = p.PageWeb.Action,
                Type = p.PageWeb.Type,
                Sidebar = p.PageWeb.Sidebar,
                BannerIsScript = p.PageWeb.BannerIsScript,
                Title = p.Title,
                Description = p.Description,
                Keywords = p.Keywords,
                ScriptHead = p.ScriptHead,
                ScriptBody = p.ScriptBody,
                BannerScript = p.BannerScript,
                BannerUrl = p.BannerUrl,
            }).ToList();
    }
}

Где PagesWebTrs - перевод страниц (многоязычный), а PagesWeb - главная таблица.

1 Ответ

0 голосов
/ 04 июня 2018

Эта проблема действительно относится к промежуточному программному обеспечению маршрута.

По определению, промежуточное программное обеспечение является одноэлементным, поэтому один экземпляр обрабатывает все запросы.Это приводит к тому, что состояние экземпляра (the IServiceConfig с подключенным DbContext) доступно и изменяется несколькими одновременными запросами;это хорошо замаскированная классическая проблема параллелизма.

Пример.

Запрос A выполняет RouteAsync, устанавливает _serviceConfig и выполняет запрос к DbContext.Нано секунд (или меньше :)) спустя, запрос B делает то же самое.В то время как запрос запроса B выполняется, запрос A выполняет GetVirtualPath, но на этот раз для DbContext, установленного запросом B. Это приводит к тому, что второй запрос выполняется на DbContext запроса B, который все еще имеет один запущенный иВы получаете упомянутое сообщение об ошибке.

Решение состоит в том, чтобы предотвратить общее состояние, извлекая IServiceConfig в начале каждого метода.

Как вы уже сказали, получение такогозависимость, введенная с помощью метода Invoke, не работает;Invoke метод не выполняется.

Здесь ниже переработанный RouteCustom.

public class RouteCustom : IRouteCustom
{
    private readonly IRouter _innerRouter;

    public RouteCustom(IRouter innerRouter)
    {
        _innerRouter = innerRouter ?? throw new ArgumentNullException(nameof(innerRouter));
    }

    public async Task RouteAsync(RouteContext context)
    {
        var serviceConfig = context.HttpContext.RequestServices.GetRequiredService<IServiceConfig>();
        // ...

    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        var serviceConfig = context.HttpContext.RequestServices.GetRequiredService<IServiceConfig>();
        // ...

    }
}
...