【发布时间】:2020-12-22 05:59:00
【问题描述】:
我了解到preferred ASP.NET-Core-way for background tasks 是hosted service。
有没有办法将(用户)session 传递给这个后台工作人员?通常会话是HttpContext 的一部分,在后台任务中不可用...
我知道我可以通过写入数据库来持久化数据,但我还想在内存中缓存一些数据。
【问题讨论】:
标签: c# asp.net-core
我了解到preferred ASP.NET-Core-way for background tasks 是hosted service。
有没有办法将(用户)session 传递给这个后台工作人员?通常会话是HttpContext 的一部分,在后台任务中不可用...
我知道我可以通过写入数据库来持久化数据,但我还想在内存中缓存一些数据。
【问题讨论】:
标签: c# asp.net-core
如果这一切都发生在进程内,那么您应该能够直接将 ISession 对象传递给您的后台服务,并让它与用户的会话进行交互,而无需用户的 HttpContext 存在。
默认会话实现是使用distributed cache 来持久化存储在会话中的信息。然后,每个会话对象仅与存储在用户 cookie 中的会话密钥进行交互。当会话对象is being created 时,不会传递对 HttpContext 的直接或间接引用。 session store itself 也不会以其他方式访问 HttpContext。分布式缓存本身也独立于上下文,也独立于 DI 服务范围。
所以至少在理论上,这应该可以正常工作。您可以使用ISession 对象来修改会话,并且下次用户使用其会话 ID 发出请求时,更新的信息将在那里等待他们。
【讨论】:
ISession 的引用可以正常工作。请记住在更改会话变量后调用CommitAsync。
不保证执行后台任务时用户会话会存在。从用户会话中封装您的任务所需的数据并将其传递给后台任务。
【讨论】:
如您所知,会话是基于此用户请求。用户拥有会话! 因此,当我们谈论会话时,实际上我们指的是从客户端收到的最终用户请求!想象一下,您在基于 aspnetcore 的微服务中有一个后台任务,没有用户请求。您永远不会看到任何要捕获的会话,因为没有用户发送任何请求。 在正常的晴天,后台任务中存在用户会话的概率非常低。 但! 如果您有想要将其用作缓存的后台服务,则应根据用户请求执行缓存读/写操作。我强烈建议您避免在后台任务中使用 HttpContext,因为您的任务将是不可扩展的,并且与 http 基础架构紧密耦合。 有一个简单的 SAMPLE :D 需要更清楚:
public interface ICache {
Task Write(string uniqueIdentifier, object data);
Task<object> Read(string uniqueIdentifier);
}
public class BackgroundTaskBasedCache : ICache {
public void Init()
{
//Initialize your background operations.
}
//IO bound
public async Task Write(string sessionId, object data)
{
//write inside your cache.
}
public async Task<object> Read(string sessionId)
{
//read from your cache.
return new object();//for test.
}
}
startup.cs:
//this will add a signleton background task. (you can do it manually or using other tools/strategies.
services.AddSingleton<ICache, BackgroundTaskBasedCache>();
在您的控制器内部:
{
public TestController(ICache cache, IHttpContextAccessor){//fill properties}
public async Task<IActionResult> ExecuteSomeRequestAction()
{
await cache.Write(httpContextAccessor.HttpContext.SessionId, data);
}
}
希望能理解并致以最诚挚的问候:)
【讨论】: