gpt4 book ai didi

c# - 用户管理器错误 "A second operation started on this context before a previous operation completed"

转载 作者:行者123 更新时间:2023-12-05 05:05:46 30 4
gpt4 key购买 nike

在我的 Blazor 服务器端应用程序中,我有多个组件,每个组件都通过依赖注入(inject)使用 UserManager,这些组件通常呈现在同一页面上。例如,我使用 NavMenu 中的 UserManager 来向用户显示/隐藏某些导航项,然后在页面本身内具有逻辑以防止导航到页面本身中的那些相同页面。通常在导航到具有此逻辑的页面时,NavMenu 和 Page UserManager 似乎发生冲突,从而导致错误:

InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

我确信这是其他人遇到过的问题,但一直未能找到解决方案。如果我在包含多个组件并注入(inject)了 UserManager 的页面上点击刷新,这种情况最常发生。我很感激能提供的任何帮助,如果需要,我可以提供更多信息!

根据请求,这是我对 UserManager 的注册。 ApplicationUserManager 目前实际上并没有覆盖 UserManager 中的任何功能,只是为了将来的定制/增强而实现:

            services.AddIdentity<WS7.Engine.Models.Identity.ApplicationUser, WS7.Engine.Models.Identity.ApplicationRole>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;

options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;

})
.AddEntityFrameworkStores<WS7.Areas.Identity.Data.ApplicationIdentityContext>()
.AddUserManager<ApplicationUserManager>()
.AddSignInManager<ApplicationSignInManager>()
.AddRoles<ApplicationRole>()
.AddDefaultTokenProviders();

可能值得注意的是,似乎因此错误而爆发的调用(基于堆栈跟踪)都在所涉及的各种组件的 OnInitializedAsync() 方法中。

两个组件的示例:组件 1:

 protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await Authorize();
}

private async Task Authorize()
{
bool allowNavigate = (AllowedRoleIds.Count() == 0);
var contextUser = _AuthorizeHttpContextAccessor.HttpContext.User;
if (contextUser != null)
{
var user = await _AuthorizeUserManager.GetUserAsync(contextUser);
if (user != null)
{
var result = await _AuthorizeIdentityService.GetUserRightsAsync(new Engine.Models.GetUserRightsParams()
{
UserID = user.Id
});
if (result.Succeeded == Engine.Models.Base.SuccessState.Succeeded)
{
if (result.UserRightIDs.Any(uri => AllowedRoleIds.Split(",").Any(ari => ari.Equals(uri, StringComparison.CurrentCultureIgnoreCase))))
{
allowNavigate = true;
}
}
}
}
if (allowNavigate == false)
{
_AuthorizeNavigationManager.NavigateTo("/Identity/Account/Login");
}
}

组件 2:

 protected override async Task OnInitializedAsync()
{
await RefreshData();
await base.OnInitializedAsync();
}

private async Task RefreshData()
{
var userAccountsResult = await _IdentityService.GetAspNetUserAccountsAsync(new Engine.Models.GetAspNetUserAccountsParams()
{
//Return all. Don't set any Params
});
if (userAccountsResult.Succeeded == SuccessState.Succeeded)
{
var users = await _userManager.Users.ToListAsync();
var usersView = users.Select(u => new UserViewModel()
{
Id = u.Id,
UserName = u.UserName,
FirstName = u.FirstName,
LastName = u.LastName,
Email = u.Email,
AccountStatus = u.ApprovedStatus,
EmailConfirmed = u.EmailConfirmed,
Active = !u.InActive,
UserAccounts = userAccountsResult.UserAccounts.Where(ua => ua.UserID == u.Id).Select(ua => new UserAccountModel()
{
Account = ua.Account
}).ToList()
}).ToList();

Users = usersView;
FilteredUsers = usersView;
}
else
{
_StatusService.SetPageStatusMessage(new PageStatusMessageEventArgs()
{
AlertType = AlertType.Danger,
Message = "There was an issue initializing the page."
});

}

}

示例异常的堆栈跟踪:

System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync() at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at WS7.Areas.Identity.Data.ApplicationUserManager.FindByIdAsync(String userId) in C:\VB6\Web\WS7\WS7\Areas\Identity\Data\ApplicationUserManager.cs:line 31 at WS7.Areas.Identity.Data.ApplicationUserManager.GetUserAsync(ClaimsPrincipal principal) in C:\VB6\Web\WS7\WS7\Areas\Identity\Data\ApplicationUserManager.cs:line 35 at WS7.Components.PDAuthorizeBase.Authorize() in C:\VB6\Web\WS7\WS7\Components\PDAuthorizeBase.cs:line 51 at WS7.Components.PDAuthorizeBase.OnInitializedAsync() in C:\VB6\Web\WS7\WS7\Components\PDAuthorizeBase.cs:line 35

最佳答案

我认为您可能会在这里找到问题的解决方案:

You should use OwningComponentBase<T> in these situations. Below is an updated sample that shows the right pattern.

Read this . See also this...

您是否在 Server Blazor 应用程序中使用 HttpContext?如果你这样做,你不应该,因为 Server Blazor App 不是基于 HTTP 的应用程序,而是基于 WebSocket 的应用程序。

希望这有助于...

关于c# - 用户管理器错误 "A second operation started on this context before a previous operation completed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60338478/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com