在 Window 服务中释放 WebApp.Start 实例的正确位置

本文关键字:实例 位置 Start WebApp Window 服务 释放 | 更新日期: 2023-09-27 18:35:38

我正在编写一个Windows服务,它将自托管OWIN WebApi Web服务。 要启动 Web 服务,位置非常明显;在 ServiceBase 扩展类的OnStart方法中:

private IDisposable _webApiDataConnectionHost;
protected override void OnStart(string[] args) {
    _webApiDataConnectionHost = WebApp.Start<OwinWebStartup>("...");
}

但是,我不确定在哪里处置 Web 应用程序。 在此示例项目中,他们在 OnStop 方法中释放它:

protected override void OnStop()
{
    if(_server != null)
    {
        _server.Dispose();
    }
    base.OnStop();
}

但是,鉴于这是一个IDisposable,在服务对Dispose方法的覆盖中处置它不是正确的吗? 如下所示:

protected override void Dispose(bool disposing) {
    if (disposing) {
        if (components != null) { components.Dispose(); }
        // Dispose of our web app if it exists...
        if (_webApiDataConnectionHost != null) {
            _webApiDataConnectionHost.Dispose();
        }
    }
    base.Dispose(disposing);
}

哪个位置是处置 Web 应用程序的合适位置?

在 Window 服务中释放 WebApp.Start 实例的正确位置

我通常设置任何服务的方式是实现 IDisposable 接口并从 OnStop 调用 Dispose 方法。我的 OnStop 通常与我的 OnPause 相同,但需要额外调用 Dispose。您可以在此处查看来自 msdn 的建议。

  • IDisposable保证了垃圾收集,迟早
    • 如果您不调用Dispose(),则收集可能会在以后不确定地发生。
  • 由于这是一项服务,因此您知道何时希望该服务停止,因此自己打电话给Dispose()是有意义的,在OnStop()中是正确的。
  • 此外,您将只运行它的单个实例 - 因此请使用单例设计模式。如果多个线程将访问单一实例,则实现线程安全模式。

如果我没看错,您在服务的覆盖Dispose()中编写的代码只是确保在对实例进行垃圾回收时,将释放所有资源。使用这种方法,您可以确保无论何时发生处置都会正确发生。您仍然需要在 OnStop() 中调用此覆盖方法。


* 我是否需要在 ASP.NET 中释放 Web 服务引用?

*关于处置ServiceBase的评论 - 也链接到Kent Cooper的回答中。