Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 每个用户使用内存缓存的ASP.NET内核_C#_Asp.net Core_Asp.net Core Mvc - Fatal编程技术网

C# 每个用户使用内存缓存的ASP.NET内核

C# 每个用户使用内存缓存的ASP.NET内核,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,我有一个系统,在某个时刻,用户将被锁定到一个页面。在这种情况下,他的帐户被锁定,无法重定向到任何其他页面,这是在身份验证之后 验证是使用访问数据库的页面过滤器完成的。为了提高性能,我使用了内存缓存 但是,结果并不像预期的那样,因为缓存一旦用于单个用户,就会影响所有其他用户 据我所知,您可以使用每个用户的标记助手来分离缓存,但我不知道使用代码是否可以实现这一点 public async Task<IActionResult> Iniciar(int paragemId, string

我有一个系统,在某个时刻,用户将被锁定到一个页面。在这种情况下,他的帐户被锁定,无法重定向到任何其他页面,这是在身份验证之后

验证是使用访问数据库的页面过滤器完成的。为了提高性能,我使用了内存缓存

但是,结果并不像预期的那样,因为缓存一旦用于单个用户,就会影响所有其他用户

据我所知,您可以使用每个用户的标记助手来分离缓存,但我不知道使用代码是否可以实现这一点

public async Task<IActionResult> Iniciar(int paragemId, string paragem)
{
    var registoId = Convert.ToInt32(User.GetRegistoId());
    if (await _paragemService.IsParagemOnGoingAsync(registoId))
    {
        return new JsonResult(new { started = false, message = "Já existe uma paragem a decorrer..." });
    }
    else
    {
        await _paragemService.RegistarInicioParagemAsync(paragemId, paragem, registoId);
        _registoService.UpdateParagem(new ProducaoRegisto(registoId)
        {
            IsParado = true
        });

        await _registoService.SaveChangesAsync();
        _cache.Set(CustomCacheEntries.RecordIsParado, true, DateTimeOffset.Now.AddHours(8));

        return new JsonResult(new { started = true, message = "Paragem Iniciada." });
    }
}
公共异步任务Iniciar(int paragemId,string paragem)
{
var registoId=Convert.ToInt32(User.GetRegistoId());
if(wait_paragemService.IsParagemOnGoingAsync(registoId))
{
返回新的JsonResult(new{started=false,message=“Jáexiste uma paragem a decorre…”);
}
其他的
{
wait_paragemService.RegistarInicioParagemAsync(paragemId,paragem,registoId);
_registoService.UpdateParagem(新产品注册库(registoId))
{
IsParado=true
});
wait_registoService.SaveChangesAsync();
_Set(CustomCacheEntries.RecordIsParado,true,DateTimeOffset.Now.AddHours(8));
返回新的JsonResult(new{started=true,message=“Paragem Iniciada.”);
}
}
在这里,我只首先检查用户帐户是否在数据库中被阻止,而不首先检查缓存,然后创建缓存条目

因此,每个用户都将被锁定


所以我的观点是。。。有没有一种方法可以像标记助手一样实现这一点?

缓存有几种替代方法。有关详细信息,请参阅此部分,其中对其进行了更详细的描述

会话状态 另一种方法是将值存储在会话状态中。这样,一个用户的会话不会干扰其他用户的会话

然而,这种方法也有一些缺点。如果会话状态保留在内存中,则无法在服务器场中运行应用程序,因为一台服务器不知道其他服务器的会话内存。因此,您需要将会话状态保存在缓存(REDIS?)或数据库中

此外,由于会话内存存储在服务器中,用户无法更改它并避免尝试实现的重定向。缺点是,这会减少服务器可以处理的用户数量,因为服务器需要每个用户具有特定的内存量

曲奇饼 您可以向客户端发送cookie,并在下一个请求到达服务器时检查此cookie。这种方法的缺点是用户可以删除cookie。如果缺少cookie的唯一结果是对数据库的请求,那么这是可以忽略的

您可以使用会话到期时服务器丢弃的会话cookie

一般的
另一个提示是,当用户注销时,您需要清除状态内存,以便在下次登录时为新用户正确设置状态。

CacheTagHelper与一般的缓存不同。它通过请求工作,因此在头或cookie值等方面可能会有所不同。直接使用
MemoryCache
IDistributedCache
是低级的;您只是直接为键添加值,所以这里没有“变化”的内容

这就是说,您可以使用经过身份验证的用户id之类的东西来编写密钥,然后在缓存中为每个用户提供一个唯一的条目,例如:

var cacheKey = $"myawesomecachekey-{User.FindFirstValue(ClaimTypes.NameIdentifier)}";

除此之外,您应该使用会话存储,这对用户来说是自动唯一的,因为它是每个会话的。

为什么不使用用户名/用户ID作为缓存的密钥?会话存储在dotnetcore中有很多注意事项(其中一个我花了2天的时间调试)。简言之,您可能会在会话值未正确更新的情况下陷入竞争状态。有关更多信息,请参阅此链接,其中明确建议不要在会话中存储活动对象: