异步调用后 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的主要内容,如果未能解决你的问题,请参考以下文章