【问题标题】:User session in background task in ASP.NET CoreASP.NET Core 后台任务中的用户会话
【发布时间】:2020-12-22 05:59:00
【问题描述】:

我了解到preferred ASP.NET-Core-way for background taskshosted service

有没有办法将(用户)session 传递给这个后台工作人员?通常会话是HttpContext 的一部分,在后台任务中不可用...

我知道我可以通过写入数据库来持久化数据,但我还想在内存中缓存一些数据。

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    如果这一切都发生在进程内,那么您应该能够直接将 ISession 对象传递给您的后台服务,并让它与用户的会话进行交互,而无需用户的 HttpContext 存在。

    默认会话实现是使用distributed cache 来持久化存储在会话中的信息。然后,每个会话对象仅与存储在用户 cookie 中的会话密钥进行交互。当会话对象is being created 时,不会传递对 HttpContext 的直接或间接引用。 session store itself 也不会以其他方式访问 HttpContext。分布式缓存本身也独立于上下文,也独立于 DI 服务范围。

    所以至少在理论上,这应该可以正常工作。您可以使用ISession 对象来修改会话,并且下次用户使用其会话 ID 发出请求时,更新的信息将在那里等待他们。

    【讨论】:

    • 已确认。存储对ISession 的引用可以正常工作。请记住在更改会话变量后调用CommitAsync
    【解决方案2】:

    不保证执行后台任务时用户会话会存在。从用户会话中封装您的任务所需的数据并将其传递给后台任务。

    【讨论】:

    • 这将允许读取会话变量,但我也需要编写它们。
    【解决方案3】:

    如您所知,会话是基于此用户请求。用户拥有会话! 因此,当我们谈论会话时,实际上我们指的是从客户端收到的最终用户请求!想象一下,您在基于 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);
         }
       }
    

    希望能理解并致以最诚挚的问候:)

    【讨论】:

    • 我想这会起作用,但它看起来很像 ASP.NET MVC 3 中的静态缓存,因此重新实现了 ASP.NET Core 提供的会话缓存。
    • 是的,亲爱的 Jack,我同意你的观点,但我认为他不想实现会话缓存,所以我试图展示一个简单的模式来改变他对使用 httpContextAccessor 和它的成本/收益。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2021-02-14
    相关资源
    最近更新 更多