在哪里实现类库或Windows服务

本文关键字:Windows 服务 类库 实现 在哪里 | 更新日期: 2023-09-27 18:25:22

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

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

有人能帮我理解吗?

在哪里实现类库或Windows服务

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

以下是一些可能影响您思考的因素:

  • 您的类库为其用户提供了一个特定的接口。对于所有调用类库的用户来说,坐在内存缓存层后面有意义吗?如果这个问题的答案是"是",那么缓存功能属于类库
  • 由于类库是一个独立的实体,因此您可能希望向库的客户隐藏一些实现细节,例如窗口的服务。如果服务要缓存数据一段时间,那么该服务将知道数据很少更改。如果不希望出现这种情况,请将缓存功能放在类库中
  • 如果数据本质上的变化比您正在编写的特定windows服务更频繁,那么缓存属于windows服务
  • 如果您计划在未来实现控制缓存状态的附加功能,例如,强制缓存无效的方法,那么该功能属于windows服务(尽管您也可以将其放在类库中,并让其用户明确控制其状态)

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

像这样的

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

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

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

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

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

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

MSDN for Memory Cache:http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

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

希望这能有所帮助。

尼科