2012-10-22 18 views
1

有很多帖子说SingleInstance是一个糟糕的设计。但我认为这是我的情况的最佳选择。
在我的服务中,我必须返回当前登录用户的列表(附加数据)。该列表对于所有客户都是相同的。我想每5秒钟从数据库中检索这个列表(例如),并在需要时将其副本返回给客户端。
如果我使用PerCall实例化模式,我会每次从数据库检索这个列表。这份清单应该包含200-500条记录,但将来可能会增长到10000条记录。每个记录都很复杂,包含大约10个字段。WCF中的单实例VS PerCall

那么性能呢?使用“糟糕的设计”并获取一次列表或在每次调用中使用“好方法”并从数据库获取列表更好吗?

回答

2

那么性能呢?使用“不好的设计”并获得 列表一次或使用“好方法”并从每个电话的 数据库获取列表更好吗?

性能和优秀的设计不互相排斥。使用单个实例的问题是它一次只能处理一个请求。所有其他请求都在等待它完成它的事情。

或者,您可以利用caching layer来保存查询的结果,而不是将其耦合到您的服务。

然后你的代码可能是这个样子:

public IEnumerable<BigDataRecord> GetBigExpensiveQuery(){ 

    //Double checked locking pattern is necessary to prevent 
    // filling the cache multiple times in a multi-threaded 
    // environment 
    if(Cache["BigQuery"] == null){ 
     lock(_bigQueryLock){ 
     if(Cache["BigQuery"] == null){ 
      var data = DoBigQuery(); 
      Cache.AddCacheItem(data, TimeSpan.FromSeconds(5)); 
     } 
     } 
    } 

    return Cache["BigQuery"]; 

} 

现在,只要你想都访问相同的缓存可以有多个实例。

+1

您可以将ConcurrencyMode设置为多个usingInstanceContextMode单一,在同一个实例上同时处理多个请求 – Soulbe

+1

@Soulbe - 但我假设他打算将数据保存在内存中。这意味着现在他必须确保他的服务实例也是线程安全的。为什么要经过所有的努力才能使用已经线程安全的'System.Runtime.Caching'? – Josh

+0

事实上,我正在考虑在多个并发模式下使用单实例:S但是您的解决方案将使我的工作变得更容易。我没有得到的东西:所有实例将共享相同的缓存?我怎么能通过定时器更新来自数据库的缓存值? – ChruS