WCF - 在呼叫之间共享/缓存数据

时间:2015-09-18 22:18:45

标签: c# wcf

我是WCF&服务开发并有以下问题。

我想编写一个依赖某些数据的服务(例如来自数据库),以便处理客户端请求并回复。 我不希望每次调用都在数据库中查找。我的问题是,是否有任何技术或方法可以预先加载或仅加载一次这样的数据,这样就不需要为每个请求获取这些数据?

我读到将InstanceContextMode设置为Single可能是一个坏主意(不完全确定原因)。有人可以解释一下处理这种情况的最佳方法。

由于

2 个答案:

答案 0 :(得分:1)

BCL有一个Lazy类用于此目的。不幸的是,在出现瞬态异常(网络问题,超时等)的情况下,它会永久存储异常。这意味着如果发生这种情况,您的服务将永远停止。这是不可接受的。因此Lazy类无法使用。微软已声明他们不愿意解决这个问题。

解决这个问题的最佳方法是编写自己的懒惰或使用等效的东西。

您也可以使用LazyInitializer。请参阅文档。

我不知道实例模式Single在异常情况下的行为方式。无论如何,将惰性资源放入服务类在架构上是不明智的。如果您想与多个服务共享这些资源,那就是一个问题。这样做也不是服务类的责任。

答案 1 :(得分:0)

这完全取决于要加载的数据量和数据使用模式。

假设您的服务调用是独立的并且可能需要不同的数据部分,那么您可以实现一些缓存(使用Lazy<T>或类似的技术)。但是这个解决方案有一个重要的警告:一旦数据被加载到缓存中,它将永远存在,除非你定义一些过期策略(基于时间或写入时刷新或其他)。如果您没有缓存条目到期策略,您的服务将随着时间的推移消耗越来越多的内存。

但是,如果您从数据库加载的数据量很小或者大多数调用一次又一次地访问相同的数据,这可能不是太重要的问题。

另一种方法是使用WCF会话(将InstanceContextMode设置为PerSession)。这将确保您在会话的生命周期内创建服务对象(在连接特定WCF客户端时将保持活动状态) - 并且来自该客户端的所有调用将被分派到同一服务对象。从业务领域的角度来看,它可能适用也可能不适用。如果这是合适的,那么您可以在第一次调用时从数据库加载数据,然后在同一会话中的后续调用将能够重用数据。新会话(重新连接后的另一个客户端或同一客户端)将不得不再次加载数据。