我遇到过这段代码:
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。这是不好的做法吗?
答案 0 :(得分:11)
让我们算一下这是不好的做法:
new 关键字是格栅,它告诉编译器关闭代码中的潜在问题。一个真实的,使用这个类的代码很容易最终调用ServiceBase.Dispose()。 ServiceBase实现了一次性模式,正确的方法是覆盖受保护的Dispose(bool)方法
Dispose()方法留下一个_threadManagers集合对象,后面只包含死对象。这使得该集合也成为一个死亡之后,之后迭代它是毫无意义的。应该已经清空
唯一可以调用此Dispose()方法的是服务终止。无法在OnStop()中执行此操作,它还处理了ServiceBase。在终结器运行之前处理“控制器”一微秒并且该过程终止是没有意义的。 Dispose()应该只用于允许尽早解除分配非托管资源。过程在一毫秒后停止
这段代码毫无意义。不要使用它。
答案 1 :(得分:3)
看起来非标准,但it is legit。所以我不一定称之为不好的做法,虽然引入混乱的事实使它成为不好的做法?
这只是作为服务运行还是存在控制台模式? (控制台应用程序不会调用OnStop。)或者是否有其他(自定义)方法来停止此服务进程?
从我之前的问题中提出的建议:
我不确定为什么
new
而不是override
,尤其是以后 正在调用base.Dispose()
。
原因:
'SomeClass.Dispose()':无法覆盖继承的成员 'System.ComponentModel.Component.Dispose()'因为它没有标记 虚拟,抽象或覆盖
换句话说,ServiceBase.Dispose的实现是不可覆盖的。
答案 2 :(得分:0)
只需添加Hans和Paul已经完美的答案:将ServiceLauncher2
声明为IDisposable
是多余的,因为ServiceBase
是Component
,而IDisposable
已经Sub OnSlideShowPageChange(ByVal Wn As SlideShowWindow)
MsgBox Wn.View.Slide.SlideIndex
End Sub
{1}}