4

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

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

有人可以帮我理解这一点吗?

4

3 回答 3

0

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

像这样的东西

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()另一个计时器之类的东西完全取决于您的选择,因为几乎不依赖于存储在其中的数据。

于 2013-07-30T01:22:51.447 回答
0

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

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

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

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

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

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

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

希望这可以帮助。

尼科

于 2013-07-30T01:39:33.447 回答
0

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

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

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