我使用WebAPI2实现了REST服务,该服务实现了管理由访问服务的不同客户创建和加入的不同会话。
会话包含有关访问应用程序功能的信息以及已加入同一会话的参与者的信息。
每个客户端从服务器获取会话信息和访问列表,以便每秒进行同步。根据访问权限的更改,客户端功能将更改(启用/禁用)。
我正在使用MemoryCache类在WebAPI服务中存储会话信息,如下所示。
customList.get(position).getAbc();
}
我的问题是关于缓存的不一致行为。
当客户端发送同步调用时,它将产生不一致的结果。对于某些请求,客户端获取正确的数据,对于某些请求,客户端在某些请求后获取空数据替换。
我添加了调试器并监视对象的null结果,然后" memoryCache.Get(" SessionCollection")" 也为null。经过一些连续的请求后,它将再次成功。我不知道为什么这个对象不是持久的。
替代方案,我已经尝试了" HttpContext.Current.Application [" SessionCollection"]" ,但同样的问题就在那里。
我已阅读" app pool recycle" ,它会在微粒时间后回收所有缓存。如果我的缓存对象被app pool recycle回收,那么我该如何再次获取此对象?
请有人帮我解决这个问题。提前谢谢。
答案 0 :(得分:1)
您应该在Session
而不是Cache
中存储客户特定信息。 Cache
应该适用于整个应用程序(共享)
但是,不推荐使用它,因为web api是基于RESTful构建的,RESTful服务应该是无状态的( API 不缓存状态)。无状态应用程序有许多好处:
如果您想存储客户端状态,无论如何都可以这样做。请尝试以下帖子中的建议:ASP.NET Web API session or something?
通常,在Web服务器上本地缓存状态很糟糕(Session
和本地MemoryCache
)。缓存可能由于多种原因而丢失:
关于您的要求:
每个客户端从服务器获取会话信息和访问列表 每秒同步的目的。根据访问权限的变化, 客户端功能将更改(启用/禁用)。
我不确定当客户端发送同步调用时是否要立即使用新访问列表更新其他客户端。如果是这样的话,SignalR将是更好的选择。
否则,您可以将更新的访问列表存储在某处(共享缓存,甚至存储在数据库中),并在其他客户端重新连接其他请求时更新其他客户端。
答案 1 :(得分:0)
请注意,MemoryCache会将数据保存在单个服务器的内存中。因此,如果您有多个Web服务器(在负载平衡器之前),则该缓存将不可用于其他服务器。您还使用缓存名称 - “SessionCollection”。该数据将分享给所有客户。如果需要将数据存储在每个客户端唯一的缓存中,则需要将一个令牌(guid)返回给客户端,并使用该令牌在后续请求中获取/更新缓存中的数据。
尝试引入类级变量。所以你的代码将如下所示。 (为清楚起见,删除了一些代码)
private readonly MemoryCache _memCache = MemoryCache.Default;
...
return _memCache.Get("SessionCollection") as List<Session>;
...
_memCache .Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5));
答案 2 :(得分:0)
答案 3 :(得分:0)
@ScottHanselman谈到了.NET 4
here中的一个错误。我希望这个修复可以帮助你:
临时修复:
在禁用的执行上下文流下创建内存缓存实例
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