持久性内存缓存中的单例模式

Fra*_*ino 5 c# architecture singleton .net-3.5

使用我认为是C#惊人文章中实现单例模式的所有世界中最好的,我已成功使用以下类来将用户定义的数据保存在内存中(对于非常少的修改数据):

public class Params
{
  static readonly Params Instance = new Params();

  Params()
  {
  }

  public static Params InMemory
  {
    get
    {
      return Instance;
    }
  }

  private IEnumerable<Localization> _localizations;

  public IEnumerable<Localization> Localizations
  {
    get
    {
      return _localizations ?? (_localizations = new Repository<Localization>().Get());
    }
  }

  public int ChunkSize
  {
    get
    {
      // Loc uses the Localizations impl
      LC.Loc("params.chunksize").To<int>();
    }
  }

  public void RebuildLocalizations()
  {
    _localizations = null;
  }

  // other similar values coming from the DB and staying in-memory,
  // and their refresh methods

}
Run Code Online (Sandbox Code Playgroud)

我的用法看起来像这样:

var allLocs = Params.InMemory.Localizations; //etc
Run Code Online (Sandbox Code Playgroud)

每当我更新数据库时,都会调用RefreshLocalizations,因此只重建了部分内存存储.我有一个大约10 生产环境,当RefreshLocalizations被调用时似乎行为不端,根本没有刷新,但这似乎也是间歇性的,而且非常奇怪.

我目前的怀疑是单身人士,我认为这项工作非常出色,而且所有的单元测试都证明了单例机制,刷新机制和RAM性能都能按预期工作.

那就是说,我对这些可能性有所了解:

  1. 当客户说他们的环境没有使用负载平衡时,这个客户撒谎,这是一个我不希望内存中的东西正常工作的设置(对吧?)
  2. 他们正在测试IIS中有一些非标准池配置(可能在Web Garden设置中?)
  3. 单身人士以某种方式失败,但不确定如何.

有什么建议?

.NET 3.5所以没有多少并行果汁,现在还没准备好使用Reactive Extensions

编辑1:根据建议,吸气剂看起来像:

public IEnumerable<Localization> Localizations
{
  get
  {
    lock(_localizations) {
      return _localizations ?? (_localizations = new Repository<Localization>().Get());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*lje 2

为了扩展我的评论,以下是如何使Localizations属性线程安全:

public class Params
{
  private object _lock = new object();

  private IEnumerable<Localization> _localizations;    
  public IEnumerable<Localization> Localizations
  {
    get
    {
      lock (_lock) {
         if ( _localizations == null ) {
            _localizations = new Repository<Localization>().Get();
         }

         return _localizations;
      }
    }
  }

  public void RebuildLocalizations()
  {
     lock(_lock) {
        _localizations = null;
     }
  }

  // other similar values coming from the DB and staying in-memory,
  // and their refresh methods

}
Run Code Online (Sandbox Code Playgroud)

  • @F.Aquino - 是的,因为您要分配给实例变量,所以您也不想锁定它,因为当您重新分配对象时,您的锁将被无意中释放。请参阅此问题的第一个答案以获得良好的解释:http://stackoverflow.com/questions/1287356/c-sharp-threading-lock-object (2认同)