【问题标题】:Where to implement caching - Class Library or Windows Service在哪里实现缓存 - 类库或 Windows 服务
【发布时间】:2013-07-29 23:53:47
【问题描述】:

我有一个 Windows 服务,它使用计时器定期调用一个类库(在工作线程上)。此类库具有所有必需的应用程序功能,Windows 服务不过是一个简单的托管环境。作为其执行的一部分,库需要调用数据库并获取一堆记录。这些记录不会经常更改(想想几周),我想将它们缓存在内存中。我应该在类库还是 Windows 服务中实现缓存结构?

基本上我有点不确定的是,一旦加载了 Windows 服务,然后定期调用这个类库,运行库的应用程序域对于库的所有执行是否保持不变(通过工作人员每隔几分钟线程一次)。因为如果不是,那么在库中实现缓存的目的似乎毫无意义。

有人可以帮我理解这个吗?

【问题讨论】:

    标签: c# caching windows-services


    【解决方案1】:

    这是一个有效的设计问题,但我认为您从错误的角度来处理它:与其考虑应用程序域和其他可能使您更难实现该功能的事情,不如从这一点考虑它属于哪里逻辑设计的观点。

    以下是一些可能会影响您思考的注意事项:

    • 您的类库向其用户提供了特定的界面。所有调用你的类库的用户都坐在内存缓存层后面是否有意义?如果这个问题的答案是“是”,那么缓存功能属于类库。
    • 由于类库是一个单独的实体,大概您希望对库的客户隐藏一些实现细节,例如窗口的服务。如果服务要将数据缓存一段时间,那么服务将拥有数据不经常更改的知识。如果不希望这样做,请将缓存功能放在类库中。
    • 如果数据本身的变化比您正在编写的特定 Windows 服务更频繁,则缓存属于 Windows 服务。
    • 如果您计划在未来实现控制缓存状态的附加功能,例如强制缓存失效的方法,那么该功能属于 Windows 服务(尽管您也可以将其放在类中)库,并让其用户明确控制其状态)。

    【讨论】:

    • 非常感谢您的回复。我无法期待更简洁的内容!
    【解决方案2】:

    在类似的情况下,我在库中实现了缓存(因为是您的主要代码库),但使其独立于主调用服务。

    类似的东西

    class ServiceRun
    {
        private MyLibrary.LibraryContext _context;
        private Timer _timer;
    
        public ServiceRun()
        {
            _context = MyLibrary.Core.InitializeBaseData();
            _timer = new Timer(10000);
            _timer.OnTick+= ()=> MyLibrary.Core.DoAction(_context);
        }
    }
    

    LibraryContext 是否应该关心它自己的完整性或服务需要调用类似_context.Refresh() 的其他计时器,这完全取决于您的选择,因为几乎不依赖于其中存储的数据。

    【讨论】:

      【解决方案3】:

      您的缓存方法将基于您的实现。根据您上面的描述,您的服务是一个简单的包装器。这个包装器调用一个(我假设通过线程)执行实际过程的类库。

      通过这种设计,我建议在类库中实现您的“缓存服务”。尽管您的库中的类正在执行然后被处置,但没有理由说明您的类库在库中的其他类完成后不能保留对缓存的引用。

      就个人而言,因为类库需要缓存对象,我看不出服务需要访问这些对象的任何原因。此外,通过在类库中维护缓存,您可以“隐藏”缓存对象。最后,另一个很大的好处是调试和错误修复会容易得多。由于您可以在任何其他应用程序中运行类库,因此您不必在 Windows 服务中进行调试,这本身就非常具有挑战性。

      我认为真正的问题是您应该使用哪种缓存,这对消耗的总内存有很大的影响。现在这是一个不同的问题。

      对于缓存,您有许多实现选项。最常见的内存缓存是使用 MemoryCache 功能作为 .Net 框架的一部分来完成的。这支持表达式策略和类似于 ASP.Net Web 实现的完整缓存包装器。

      内存缓存的 MSDN:http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

      最后,在我看来,我可能会使用 Singletons 或通过 DependencyInjection 将您的缓存系统包装到另一个类中以维护缓存的对象。

      希望这会有所帮助。

      尼哥

      【讨论】:

      • 非常感谢您的回复,希望我能在此处将两个回复标记为答案。我肯定会保留你和 dasblinkelight 在处理这个问题时所说的话。 MemoryCache 对我来说也是新的,感谢那里的指针!
      猜你喜欢
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2017-01-29
      • 2014-10-18
      • 1970-01-01
      相关资源
      最近更新 更多