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

これが悪い習慣である方法を数えましょう。

  • 新しいキーワードはグレーティングです。これは、コード内の潜在的な問題について沈黙するようコンパイラーに指示します。実際には、このクラスを使用するコードは、代わりに ServiceBase.Dispose() を簡単に呼び出してしまう可能性があります。ServiceBase は使い捨てパターンを実装します。これを行う正しい方法は、保護された Dispose(bool) メソッドをオーバーライドすることです

  • Dispose() メソッドは、死んだオブジェクトだけを含む _threadManagers コレクション オブジェクトを残します。これにより、コレクションはドアネイルとしても機能しなくなり、後で繰り返しても意味がありません。空にするべきだった

  • この Dispose() メソッドを呼び出すことができるのは、サービスの終了時のみです。OnStop() では実行できません。ServiceBase も破棄されました。ファイナライザーが実行されてプロセスが終了する1マイクロ秒前に「コントローラー」を破棄しても意味がありません。Dispose() は、管理されていないリソースの割り当てを早期に解除できるようにするためにのみ使用してください。プロセスが 1 ミリ秒後に停止する早期はありません

このコードは意味がありません。使用しないでください。

于 2013-03-12T19:52:52.240 に答える
3

非標準に見えますが、合法です。だから私は必ずしもそれを悪い習慣とは呼びませんが、混乱を招くという事実はそれを悪い習慣にしていますか?

これはサービスとしてのみ実行されますか、それともコンソール モードはありますか? (コンソール アプリでは OnStop が呼び出されません。) または、このサービス プロセスを停止する他の (カスタム) 方法はありますか?

私自身の以前の質問から修正します:

特に が呼び出されているため、newの代わりに理由がわかりません。overridebase.Dispose()

理由:

'SomeClass.Dispose()': 継承されたメンバー 'System.ComponentModel.Component.Dispose()' は、仮想、抽象、またはオーバーライドとマークされていないため、オーバーライドできません

つまり、ServiceBase.Dispose の実装はオーバーライドできません。

于 2013-03-12T19:00:36.020 に答える