ASP.NET会话被覆盖

时间:2019-01-28 16:48:55

标签: c# asp.net

我处于这样的情况:两个调用同时写入会话(运行在旧框架上的asp.net核心应用程序的会话),并且其中一个会话变量被覆盖。

给出以下控制器代码,假设首先调用长会话,然后在200毫秒后调用短会话,然后在800毫秒后(长会话完成时)调用两个会话的结果。

[HttpPost("[action]")]
public async Task<IActionResult> TestLongSession() {
    HttpContext.Session.SetString("testb", "true");

    // If we do this delay BEFORE the session ("testb") is set, then all is fine.
    await Task.Delay(1000);

    return Ok();
}

[HttpPost("[action]")]
public async Task<IActionResult> TestShortSession() {
    HttpContext.Session.SetString("testa", "true");

    return Ok();
}

[HttpGet("[action]")]
public async Task<IActionResult> TestResultOfBothSessions() {
    string a = HttpContext.Session.GetString("testa");
    string b = HttpContext.Session.GetString("testb");

    return Ok($"A: {a}, B: {b}");
}

最终调用(TestBothSessions)的结果为"A: , B: true"

然后的问题是:是否有一些我无法使会话正常运行的东西(又名,返回"A: true, B: true")?

很明显,我可以消除延迟,并且一切都很好,但是在实际的应用程序中,有一个调用可能会花费一些时间,并且我不希望以后再编写会话变量(我想我可以使用自定义错误处理,但问题仍然存在,我不再信任asp.net会话可用于同步调用。

编辑:从浏览器调用这些端点的打字稿代码:

this.service.testLongSession().subscribe(() => {
    this.service.testBothSessions().subscribe((result: string) => {
        console.log(result);
    });
});
setTimeout(() => {
    this.service.testShortSession().subscribe();
}, 200);

1 个答案:

答案 0 :(得分:1)

我相信您观察到的行为就是ASP.NET作者的意图。我查看了会话存储需要实现的接口,即ISessionISessionStore,但没有看到同步机制来防止在同时请求期间覆盖数据。

这种简单的界面的好处是它易于实现,并且可以通过各种缓存和数据库轻松实现。

ASP.NET 4的会话存储基类SessionStateStoreProviderBase更为复杂,其中包括锁定逻辑,但是实现起来确实具有挑战性。

相关问题