如何在ASP.NET WebApi2中管理缓存?

我已经使用WebAPI2实现了REST服务,该服务实现为管理由访问服务的不同客户端创建和加入的不同会话。

会话包含有关访问应用程序function的信息以及已加入同一会话的参与者的信息。

每个客户端从服务器获取会话信息和访问列表,以便每秒进行同步。 根据访问权限的更改,客户端function将更改(启用/禁用)。

我正在使用MemoryCache类在WebAPI服务中存储会话信息,如下所示。

public static class SessionManager{ private static object objForLock = new object(); public static List SessionCollection { get { lock (objForLock) { MemoryCache memoryCache = MemoryCache.Default; return memoryCache.Get("SessionCollection") as List; // return HttpContext.Current.Application["SessionCollection"] as List; } } set { lock (objForLock) { MemoryCache memoryCache = MemoryCache.Default; memoryCache.Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5)); //HttpContext.Current.Application["SessionCollection"] = value; } } } 

}

我的问题是关于缓存的不一致行为。

当客户端发送同步调用时,它将产生不一致的结果。 对于某些请求,客户端获取正确的数据,对于某些请求,客户端在某些请求后获取空数据替代。

我添加了调试器并监视对象的null结果,然后“memoryCache.Get(”SessionCollection“)”也为null。 经过一些连续的请求后,它将再次成功。 我不知道为什么这个对象不持久。

另外,我也试过“HttpContext.Current.Application [”SessionCollection“]” ,但同样的问题就在那里。

我读过“app pool recycle” ,它在微粒时间后回收所有缓存。 如果我的缓存对象被app pool recycle回收,那么我该如何再次获取此对象?

请一些人帮我解决这个问题。 提前致谢。

您应该将客户端特定信息存储在Session而不是CacheCache应该适用于整个应用程序(共享)

但是,不推荐使用,因为Web api是基于RESTful构建的,RESTful服务应该是无状态的( API不缓存状态)。 无状态应用程序有许多好处:

  • 减少内存使用量
  • 更好的可扩展性:您的应用程 图像如果您同时存储数百万客户的信息会发生什么。
  • 更好的负载平衡方案:每个服务器都可以处理每个客户端而不会丢失状态
  • 会话到期问题。

如果您想存储客户端状态,无论如何都可以这样做。 请尝试以下post中的建议: ASP.NET Web API会话或其他什么?

通常,在Web服务器上本地缓存状态是错误的( Session和本地MemoryCache )。 缓存可能由于多种原因而丢失:

  • 应用程序池回收。
  • 负载均衡环境
  • IIS中的多个工作进程

关于您的要求:

每个客户端从服务器获取会话信息和访问列表,以便每秒进行同步。 根据访问权限的更改,客户端function将更改(启用/禁用)。

当客户端发送同步调用时,我不确定是否要立即使用新访问列表更新其他客户端。 如果是这样的话, SignalR将是更好的选择。

否则,您可以将更新的访问列表存储在某处(共享缓存甚至数据库中),并在其他客户端重新连接另一个请求时更新其他客户端。

请注意,MemoryCache会将数据保存在单个服务器的内存中。 因此,如果您有多个Web服务器(在负载平衡器之前),则该缓存将不可用于其他服务器。 您还使用缓存名称 – “SessionCollection”。 该数据将与所有客户共享。 如果需要将数据存储在每个客户端唯一的缓存中,则需要将令牌(guid)返回给客户端,并使用该令牌在后续请求中获取/更新缓存中的数据。

尝试引入一个类级变量。 所以你的代码将如下所示。 (为清楚起见删除了一些代码)

 private readonly MemoryCache _memCache = MemoryCache.Default; 

….

 return _memCache.Get("SessionCollection") as List; 

 _memCache .Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5)); 

我希望这篇文章会对你有所帮助。

https://damienbod.com/2014/05/18/exploring-web-api-2-caching/

@ScottHanselman在这里谈到了.NET 4一个错误。 我希望这个修复可以帮助你:

临时修复

在禁用的执行上下文流下创建内存缓存实例

 using (ExecutionContext.SuppressFlow()) { // Create memory cache instance under disabled execution context flow return new YourCacheThing.GeneralMemoryCache(…); } 

该修补程序是http://support.microsoft.com/kb/2828843 ,您可以在此处请求: https : //support.microsoft.com/contactus/emailcontact.aspx?scid = sw;%5BLN%5D; 1422