3

Ninject で DI 用にプロジェクトをリファクタリングする前に、単純なメソッドを持つ単純なテスト クラスがありました。

    public void TestImport()
    {
        var functionality = new ImportFunctionality();
        functionality.Execute();
    }

この「アプリ」(私のライブラリを統合テストするための単なるサンドボックス WPF クライアント アプリ) を実行すると、「メイン」ウィンドウが表示され、このTestImportメソッドと呼ばれるそのウィンドウのボタンをクリックすると、実行され、テストとデバッグが可能になりました。私のコード、そしてメインウィンドウが閉じられると、アプリはすぐに終了し、VSはデバッグモードを終了します. 通常のもの。

次に、全体をリファクタリングし、コード全体に Ninject、ファクトリ、インターフェイスを使用して依存性注入を実装しました。メソッドは次のようになりTestImportます。

    public void TestImport()
    {
        using (var kernel = new StandardKernel())
        {
            kernel.Load<SecurityNinjectModule>();
            kernel.Load<HelpersNinjectModule>();
            kernel.Load<ImportFunctionalityNinjectModule>();

            var functionality = kernel.Get<IImportFunctionality>();
            functionality.Execute();
        }
    }

WPFサンドボックス/テストアプリを実行すると、すべてが機能し、「メイン」ウィンドウが閉じられ、アプリケーションが終了せず、Visual Studioがデバッグモードのままになることを除いて、それは素晴らしいことです. Dispose()それを修正するために呼び出しを追加しましたが、うまくいきませんでした。ブロックでラップしてusingも修正されません。

ボタンをクリックせずにサンドボックスを実行してTestImportメソッドを実行し、メイン ウィンドウを閉じると、アプリは適切にシャットダウンします。

これにより、Ninject カーネル オブジェクトにたどり着きます。Dispose()呼び出しにもかかわらず、何らかの形でリソースを保持している可能性はありますか? それでは、Ninject 3.0 を実行しているアプリケーションを適切にシャットダウンするにはどうすればよいでしょうか?

EDIT デバッグ/ウィンドウ/スレッドウィンドウを表示すると、インスタンス化されたすべてのスレッドがスリープしているか、「スリープ中、待機中、または参加中」のいずれかが表示されます。という名前のスレッド.NET System Eventsは、スリープ中、待機中、または参加中です。vshost.RunParkingWindowメイン スレッドは「ネイティブ トランジションへの管理」と呼ばれるスレッドです。. 受け入れられれば答えはうまくいくようですが、@BahriGungorが言うように、「System.Environment.Exitを使用することは、出口標識に従いたくなかったため、ダイナマイトを使用してドアを作ることによく似ています」。そして、なぜこれが起こっているのかは述べていません。

興味深いことに、一貫して発生するわけではありません。コードを中断してステップ スルーすることがあり、「F5」キーを押して再開し、メイン ウィンドウを閉じると、適切にシャットダウンします。どうしたの?

EDIT 2 機能により が表示され、FileDialogそのダイアログが Excel ワークブックのファイル名を返さない場合、インポート ウィンドウは表示されません。私はこれにそれを絞り込みました:

  • インポート ビューが表示されている場合、メイン アプリ ウィンドウを閉じた後にどのように閉じても、VS はデバッグ モードを適切に終了します。
  • インポート ビューが表示されない (つまり、FileDialog編集可能なものが返されない) 場合、VSはメイン アプリ ウィンドウを閉じた後、デバッグ モードを終了しません。
4

1 に答える 1

1

DIには、DI コードの 99% が存在するコンポジション ルートが必要です。ファクトリは、依存性注入の 1% のケースである必要があります。onStartupメソッドである WPF の場合

また、DI のライフタイム管理部分を指定するコードのどこにも表示されません。生涯管理別名を指定していない場合は、生涯管理Bind<Samurai>().ToSelf().InSingletonScope();も廃棄も行われない可能性があります。ninject のスコープに関する情報は次のとおりです。

途中で破棄するための呼び出しを追加したと言いますが、弱参照なしでイベントリスナーを設定すると、破棄の欠如につながるメモリリークが発生する可能性があります。

最後に、リンクされた質問の他の回答に従いましたSystem.Environment.Exitか? デバッガーで Application.Current.Windows コレクションをチェックして、問題のあるウィンドウを見つけます。 https://stackoverflow.com/a/7349650/57883

再現可能かどうかを確認するために、他の win フォーム ダイアログまたは 1 つだけを使用してみましたか?

于 2013-05-06T12:39:36.583 に答える