gpt4 book ai didi

AuthorizeAttribute 上的 C# 线程安全 CreateIdentityAsync

转载 作者:行者123 更新时间:2023-12-02 02:26:58 31 4
gpt4 key购买 nike

如果我做了more than one API调用同时出现错误

A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method in this context. Any instance members are not guaranteed to be thread-safe.

var identity = await base.currentUserService.CreateIdentity(user);抛出异常因为两个请求是同时发出的,并且前一个请求的 CreateIdentity 方法还没有完成!

如何解决上述场景?

我想等IsValidRequest调用CustomKeyAuthenticationAttribute在上一个请求完成之前。

这里是示例代码

public class CustomKeyAuthenticationAttribute : AuthorizeAttribute
{
[Dependency]
public IAuthService AuthService { get; set; }

public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var isValid = await AuthService.IsValidRequest(key-from-request-header);
if(!isValid){
return;
}
await base.OnAuthorizationAsync(actionContext, cancellationToken);
}
}

// In side AuthService
public async Task<bool> IsValidRequest(string key)
{
if (key-in-db)
{
var user = await base.currentUserService.GetUserById(userId-from-request-headers);

var identity = await base.currentUserService.CreateIdentity(user);

var principal = new GenericPrincipal(identity.Result, new string[0]);

HttpContext.Current.User = principal;

return true;
}
return false
}

// Inside currentUserService.CreateIdentity method

public async Task<ClaimsIdentity> CreateIdentity(CustomUser user) {
return await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
}

编辑

stackTrace: " atSystem.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered() atSystem.Data.Entity.Internal.Linq.InternalSet1.FindAsync(CancellationToken cancellationToken, Object[] keyValues) at System.Data.Entity.DbSet1.FindAsync(CancellationTokencancellationToken, Object[] keyValues) atSystem.Data.Entity.DbSet1.FindAsync(Object[] keyValues) at Microsoft.AspNet.Identity.EntityFramework.EntityStore1.GetByIdAsync(Objectid) atMicrosoft.AspNet.Identity.EntityFramework.UserStore6.<GetUserAggregateAsync>d__6c.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNet.Identity.TaskExtensions.CultureAwaiter1.GetResult()atMicrosoft.AspNet.Identity.UserManager2.<GetRolesAsync>d__ac.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNet.Identity.TaskExtensions.CultureAwaiter1.GetResult()atMicrosoft.AspNet.Identity.ClaimsIdentityFactory2.<CreateAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()

最佳答案

我需要查看背后的代码

var identity =  await base.currentUserService.CreateIdentity(user);

但我的猜测是您将 DbContext 设置为各个请求之间的共享实例。您需要为每个线程使用不同的上下文。

检查this question here for more information因为我认为这是同样的问题。

另一个类似的问题on entity framwork documentation

关于AuthorizeAttribute 上的 C# 线程安全 CreateIdentityAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59390740/

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