【问题标题】:HttpContext.Current null in async after await calls等待调用后异步中的 HttpContext.Current null
【发布时间】:2015-12-20 06:38:33
【问题描述】:

在 await 调用之后,HttpContext.Current null 处于异步状态。

这是我的代码:

if (!string.IsNullOrEmpty(securityGroupName))
{
    // To remove the domain name from the security group name.
    string securityGroupDisplayName = securityGroupName.Split('\\')[1];
    string serviceSecurityGroupId = await this.graphApiClient.GetGroupIdAsync(securityGroupDisplayName).ConfigureAwait(false);

    if (!string.IsNullOrEmpty(serviceSecurityGroupId))
    {
        Task securityGroupRoleAddTask = this.CheckMembershipAndAddRole(serviceSecurityGroupId, userId, securityGroupName);
        Task flightAdminRoleAddTask = this.CheckMembershipAndAddRole(FlightAdminSecurityGroupId, userId, FlightAdminRoleName);
        Task.WaitAll(securityGroupRoleAddTask, flightAdminRoleAddTask);
    }
    else
    {
        LoggingUtilities.Logger.TraceInformation("Azure AD id does not exist for the security group: {0}.", securityGroupName);
        await this.CheckMembershipAndAddRole(FlightAdminSecurityGroupId, userId, FlightAdminRoleName).ConfigureAwait(false);
    }
}
else
{
    LoggingUtilities.Logger.TraceInformation("Security group name is not valid, checking for flight admin role for the user: {0}.", userAlias);
    await this.CheckMembershipAndAddRole(FlightAdminSecurityGroupId, userId, FlightAdminRoleName).ConfigureAwait(false);
}

// Add the flight privileged users role to be able to verify the user is authorized for the role.
string flightPrivilegedUsersRoleName = RoleRepository.Instance.GetByName(Constants.FlightPrivilegedUsersRoleKey).Name;
if (!this.roles.Contains(flightPrivilegedUsersRoleName, StringComparer.OrdinalIgnoreCase))
{
    LoggingUtilities.Logger.TraceInformation("Adding flight privileged users to roles list for the user: {0}.", userAlias);
    this.roles.Add(flightPrivilegedUsersRoleName);
}

if (userAlias != null)
{
    LoggingUtilities.Logger.TraceInformation("Check security group memberships and assign roles for the user: {0}.", userAlias);
    var newPrincipal = new GenericPrincipal(new GenericIdentity(userAlias), this.roles.ToArray());
    Thread.CurrentPrincipal = newPrincipal;
    HttpContext.Current.User = newPrincipal;
}

关于 web.config 条目中以下条目的建议没有帮助:

<system.web>
    <compilation debug="false" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" enableVersionHeader="false" requestPathInvalidCharacters="&lt;,&gt;,%,&amp;,\,?" />
</system.web>
<appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>

任何有关如何解决此问题的建议将不胜感激。

【问题讨论】:

  • 显示你的异步代码。

标签: c# asp.net-web-api async-await httpcontext


【解决方案1】:

删除您的.ConfigureAwait(false) 电话。他们是什么给你带来麻烦。当您调用 .ConfigureAwait(false) 时,它会告诉 C# 您不在乎使用哪个线程来完成异步调用。您最终会进入另一个没有 HttpContext.Current 上下文的线程,因为它是线程池线程,而不是 ASP.NET 线程。

【讨论】:

  • 删除 .ConfigureAwait(false) 会阻止 Task.WaitAll(securityGroupRoleAddTask, flightAdminRoleAddTask) 上的执行;陈述。在没有死锁的情况下解决这个问题的正确方法是什么。
  • 您应该改用await Task.WhenAll()。一般来说,您不应该混合使用异步调用和阻塞调用。
  • 从整个类中删除 .ConfigureAwait(false) 并添加 await Task.WhenAll() 代替 Task.WaitAll 会引发异常:System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)
  • 发布整个异常文本
  • 两次等待​​是不正确的。而ConfigureWait(false) 总是会导致您丢失 ASP.NET 中的上下文。它不应该被使用。
猜你喜欢
  • 2018-07-27
  • 2013-10-07
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多