异步调用后 UserContext 变为 null

Posted

技术标签:

【中文标题】异步调用后 UserContext 变为 null【英文标题】:UserContext becomes null after async call 【发布时间】:2020-11-11 21:53:36 【问题描述】:

我的函数 Verify 中有一个 Web 服务调用。 代码如下:

public async Task<ActionResult> Index()

    ....
    
    UserContext.LoginUser = null;

    if (!string.IsNullOrEmpty(etoken))
    
        SSOLogin ssoLogin = new SSOLogin();
        LoginUser user = await ssoLogin.Verify(etoken);
        UserContext.LoginUser = user;
        if (UserContext.LoginUser == null)
            return RedirectToAction("UnAuthorized", "Login");
        else
        
            Session["authenticated"] = true;
            userId = UserContext.LoginUser.UserId;
            domain = UserContext.LoginUser.Domain;
        
    


public async Task<LoginUser> Verify(string etoken)

    string publicKey = "xxx";

    LoginUser loginUser = null;

    WSVerifyAccessToken wsVerifyAccessToken = new WSVerifyAccessToken();
    string verifyResponse = await wsVerifyAccessToken.VerifyAccessToken(etoken); // Inside, this is a web service call

    if (!string.IsNullOrEmpty(verifyResponse))
    
        /* Some processing here */
    


    return loginUser;

问题是,Verify 函数后 UserContext 变为 null

LoginUser user = await ssoLogin.Verify(etoken);

因此当我分配时

UserContext.LoginUser = user;

给我错误System.NullReferenceException: Object reference not set to an instance of an object.

我试图使函数同步

LoginUser user = await ssoLogin.Verify(etoken).Result;

但是 Web 服务调用会一直挂在那里并且永远不会结束。

有什么办法吗?

【问题讨论】:

请分享minimal reproducible example。 【参考方案1】:

当 web.config 文件中的 runtime 目标框架为 4.0 而不是 4.5 或更高版本时,这是一个已知问题。这可能与您的项目设置的目标框架不同。 Make sure that the runtime target framework is 4.5 or higher.

另外: UserContext 绑定到初始化请求的线程。因此,您应该将等待调用的回调返回到原始上下文。即使 ConfigureAwait(true) 是默认值,您也应该通过指定以下内容来确保在回调中使用正确的上下文:

UserContext.LoginUser = await ssoLogin.Verify(etoken).ConfigureAwait(true);

查看配置等待方法here更详细的描述

【讨论】:

.ConfigureAwait(true);不是默认的吗? @mjwills,是的,你是对的。我的 Roslyn 分析器已经把我逼到了我总是明确表示这一点的地步:)。 @rcs,另外,在 web.config 设置中检查您的运行时目标框架。我已经用参考更新了我的答案。这可能与您项目的框架版本不同。 如果我使用的是 4.7 怎么办?我尽量不降级我的 .net 框架版本 Target 版本和 Runtime 版本之间存在差异。只要确保 RUNTIME 版本没有被设置为 4.0。

以上是关于异步调用后 UserContext 变为 null的主要内容,如果未能解决你的问题,请参考以下文章

var 变量在函数调用后变为 null

Lambda函数在调用回调后返回null

ArrayList 突然变为 null 之前不为 null

两个异步请求成功后执行第三个异步函数

从对话框片段返回后,工具栏视图引用变为null

使用异步任务时光标变为空?