【问题标题】:Single Instance VS PerCall in WCFWCF 中的单实例 VS PerCall
【发布时间】:2012-10-22 15:47:09
【问题描述】:

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

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

【问题讨论】:

    标签: wcf performance concurrency instance


    【解决方案1】:

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

    性能和良好的设计并不相互排斥。使用单个实例的问题是它一次只能服务一个请求。所以所有其他请求都在等待它完成它的事情。

    或者,您可以只利用 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"];
    
    }
    

    现在您可以拥有任意数量的实例来访问同一个缓存。

    【讨论】:

    • 您可以将 ConcurrencyMode 设置为多个 usingInstanceContextMode Single,以同时在同一实例上服务多个请求
    • @Soulbe - 但我假设他打算将数据保存在内存中。这意味着现在他必须确保他的服务实例也是线程安全的。当您可以使用已经是线程安全的 System.Runtime.Caching 时,为什么还要付出所有努力?
    • 事实上我正在考虑使用具有多个并发模式的单个实例:S 但是您的解决方案将使我的工作更容易。我没有得到的东西:所有实例都将共享相同的缓存?如何通过计时器更新数据库中的缓存值?
    • @ChruS - 你不必这样做。只需将缓存值设置为从现在起 5 秒的绝对超时。这样,第一个在 5 秒后请求值的人会填充缓存,任何后续调用都将提取缓存的值。这样做的好处是在没有人请求数据时不会访问数据库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2011-10-30
    • 2015-01-12
    • 2019-07-20
    • 1970-01-01
    相关资源
    最近更新 更多