4

私の特定のコンテキストは、RavenDb 埋め込みドキュメント データベースを使用している自己ホスト型の Nancy アプリケーションです。

私のブートストラップは次のようになります。

public class MyBootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);

        container.Register<IDocumentStore>(CreateDefaultStore());
        container.Register<IDoSomething, MyOtherType>().AsSingleton(); // implements IDisposable
    }

    private static IDocumentStore CreateDefaultStore(){...}
}

問題は、IDocumentStore の Dispose メソッドと、NanyHost が停止したときにカスタムの使い捨て型が呼び出されることを期待していたことです。

NancyHost は IDisposable を実装し、TinyIoCContainer は IDisposable を実装します。IDisposable を実装する型をリクエスト コンテナーに登録すると、破棄されます。ホストが破棄されるとコンテナが破棄され、登録されているすべてのインスタンスが破棄されることはほぼ確実でした。

ブートストラップの外部にドキュメント ストアへの参照を保存し、ホストが停止した後にそれを破棄できることはわかっています。また、ブートストラップに IDisposable を実装させ、ホストが停止した後に手動で破棄するなどの他のトリックも考えられますが、ホッピングしていました。登録されたすべてのインスタンスの破棄をより自動的に処理する方法があることを確認してください。

アプリケーション コンテナーに登録されているシングルトン インスタンスで Dispose() を呼び出す賢い方法がありませんか?

私の推測では、ホストとアプリケーション コンテナーはアプリケーションが終了するまで存続することが期待されているため、コンテナーを破棄することは優先事項ではありませんでしたが、それでも、そうであれば、これは悪い習慣のように思えます。

更新: 投稿後、nancy グループでこのスレッドを見つけました。このスレッドには、これに関連する情報がありますが、少し古いです。

4

2 に答える 2

2

あなたが提供するソースを読むと、RavenDb は IDIsposable パターンを完全には実装していません。ベスト プラクティスによると、IDisposable を実装するクラスには、アンマネージ リソースを消去するファイナライザーが必要です。その場合、GC は必要なことは何でも行います。

あなたが提供した RavenDb コードでは、Dispose メソッドは管理されていないリソースを処理しないため、呼び出されていない場合でもリークは発生しません。もちろん、これは、によって参照される管理対象リソースが、管理対象外のリソースEmbeddableDocumentStoreを保持している場合、「適切な」IDisposable パターンが実装されていることを前提としています (私はそれを確認していません)。

それでも懸念がある場合は、次のことができます。

  1. RavenDb に対してバグ リクエストを提出し、修正してもらいます。
  2. IDisposable パターンを正しく実装する DocumentStore のラッパーを使用します。

いずれにせよ、証明されたバグ/ニーズが存在しない限り、「.Netフレームワークを中継して仕事をする」ことは悪いことだとは思いません。アプリケーション コンテナがアプリケーションのライフサイクル全体にわたって存在することが前提であるため、アプリケーションが終了すると、GC が適切な破棄を処理します。

于 2013-10-16T13:00:30.830 に答える
2

これはアプリのシャットダウンには必要ありませんが、自己ホスト型および OWIN のシナリオでは、AppDomain を破棄せずにサーバー コンポーネントを「再起動」することができます。これらのシナリオでは、ファイナライズについてより決定論的であることが明らかに有益です。

そのために、ブートストラップを破棄できるように変更し、ブートストラップの基本クラスでアプリ コンテナーを破棄し (IDisposable を実装している場合)、ホストが破棄されたときにすべてを破棄するようにホスティングを配線しました。

https://github.com/NancyFx/Nancy/pull/1268

于 2013-10-17T08:41:27.240 に答える