8

我遇到过这段代码:

public class ServiceLauncher2 : ServiceBase, IDisposable

然后这个:

        /// <summary>
        /// Disposes the controllers
        /// </summary>
        // This is declared new as opposed to override because the base class has to be able to
        // call its own Dispose(bool) method and not this one. We could just as easily name
        // this method something different, but keeping it Dispose is just as valid. 
        public new void Dispose()
        {
            foreach (var mgr in _threadManagers)
                mgr.Dispose();
            base.Dispose();
        }

我以前从未在 Windows 服务实现中看到过这种情况。通常只覆盖 OnStop/OnStart。这是不好的做法吗?

4

3 回答 3

12

让我们计算一下这是不好的做法:

  • 新关键字是 grating,它告诉编译器关闭代码中潜在问题。一个真实的,使用这个类的代码很容易最终调用 ServiceBase.Dispose() 。ServiceBase 实现了一次性模式,正确的做法是重写受保护的 Dispose(bool) 方法

  • Dispose() 方法留下一个 _threadManagers 集合对象,该集合对象只包含死对象。这也使该集合像门钉一样死去,之后对其进行迭代是没有意义的。应该是清空的

  • 唯一可以调用此 Dispose() 方法的时间是在服务终止时。在 OnStop() 中做不到,它还处理了 ServiceBase。在终结器运行和进程终止之前一微秒处置“控制器”是没有意义的。Dispose() 应该只用于允许提前释放非托管资源。进程在一毫秒后停止时没有早

这段代码没有意义。不要使用它。

于 2013-03-12T19:52:52.240 回答
3

它看起来确实不标准,但它是合法的。因此,我不一定将其称为不好的做法,尽管它引入混乱的事实使它成为不好的做法?

这仅作为服务运行还是有控制台模式?(控制台应用程序不会调用 OnStop。)或者是否有其他(自定义)方法来停止此服务进程?

修改我自己之前的问题:

我不知道为什么new而不是override,尤其是因为 base.Dispose()被调用了。

原因:

“SomeClass.Dispose()”:无法覆盖继承的成员“System.ComponentModel.Component.Dispose()”,因为它未标记为虚拟、抽象或覆盖

换句话说,ServiceBase.Dispose 的实现是不可覆盖的。

于 2013-03-12T19:00:36.020 回答
0

只是为了补充 Hans 和 Paul 已经完美的答案:声明ServiceLauncher2asIDisposable是多余的, as ServiceBaseis a Componentwhich 反过来已经是IDisposable

于 2017-10-03T15:11:24.883 回答