EF。連接沒有關閉。連接的當前狀態是連接

asp.net asp.net-core c# entity-framework entity-framework-core

我有jwt auth:

var messageHandlers = new JwtMessageHandler(_serviceProvider);

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    Events = new JwtBearerEvents
    {
        OnMessageReceived = messageHandlers.OnMessageReceived,
    },
    TokenValidationParameters = tokenValidationParameters
});

JwtMessageHandler是我的自定義處理程序。在處理程序中,我必須對數據庫進行一些查詢,因此我傳遞ServiceProvider並解析我的用戶服務:

public class JwtMessageHandler
{

        private IUserService _userService;  

        public async Task OnMessageReceived(MessageReceivedContext arg)
        {
             //parsing header, get claims from token
             ...
              _userService = (IUserService)arg.HttpContext.RequestServices.GetService(typeof(IUserService));
             var isRoleChanged = await _userService.IsRoleChanged(tokenObject.Subject, rolesFromToken);

            if (isRoleChanged)
            {
                GenerateBadResponse(arg);
                return;
            }

            var canLogin = await _userService.CanLogin(tokenObject.Subject);

            if (!canLogin)
            {
                GenerateBadResponse(arg);
                return;
            }
        }    
}

在服務中我提出查詢:

...
 var user = await _userManager.FindByEmailAsync(email);
 var currentRoles = await _userManager.GetRolesAsync(user);
..

為每個請求調用OnMessageReceived 。當我在服務器頁面上有一個請求或我在做某事之前等待一兩秒鐘一切正常。但是,我有幾個頁面,我同時向服務器發出2-3個請求。並且,在這種情況下,我得到錯誤:

連接沒有關閉。連接的當前狀態是連接

我理解多線程的問題。應用程序啟動時,會創建一次JwtMessageHandler 。所以,我把這條線:

_userService = (IUserService)_serviceProvider.GetService(typeof(IUserService)); 

inside方法,在它位於構造函數中之前。但是,它沒有幫助。另外,我嘗試在方法的最後將null設置為_userService

在這種情況下如何正確使用?

一般承認的答案

嘗試使用已經“連接”的連接 - 清楚某些競爭條件的跡象。

  1. 重新檢查IUserService是否已註冊“scope”生命週期,以及所有依賴項(userManager,dbContext)
  2. 不要使用在應用程序啟動期間獲得的IServiceProvider來進行基於範圍的服務解析 - 它與當前請求範圍無關,並且從“其他某個Universe”返回實例。使用HttpContext.RequestServices進行服務解析。
  3. 檢查您是否“等待”所有異步方法。如果在仍然執行第一個請求時啟動第二個請求 - 您可能在“連接”階段“捕獲”dbContext。
  4. 您的JwtMessageHandler實例是每個應用程序一個/單個。所以不要使用它的屬性來存儲_userService (刪除private IUserService _userService )。相反,使用局部變量裡面OnMessageReceivedvar _userService = ... )。

您已經檢查過(1),(2)和(3)。我認為(4)是你需要修復bug的最後一個。


熱門答案

@Dmitry的回答指出了我正確的方向。對我來說,我在.NETCORE的MiddleWare中遇到了這個問題。為我解決這個問題的是在我的中間件的Invoke方法中解析IUnitOfWork接口。

我做了類似的事情

public Task Invoke(HttpContext context)
{
    _unitOfWork = (IUnitOfWork)context.RequestServices.GetService(typeof(IUnitOfWork));

       //Some checks            

        var apiKey = context.Request.Headers["X-ApiKey"][0];

        var clientApp = _unitOfWork.ClientApplicationsRepository.Items.FirstOrDefault(s => s.ApiKey == apiKey);

     //Some other code...

    return _next(context);
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow