0

MessengerクラスがMVVM-LightのICleanupでどのように機能するかを明確にするために少し助けが必要です。Mvvm-Lightv4を使用してVB.NetでWPF4アプリケーションを作成しています。

次のように作成したNavigationServiceクラスから送信されたメッセージを登録するメッセンジャーがあります。

これは、ClientListViewModelという名前のViewModelへの登録です。

 ''register for messages
  Messenger.[Default].Register(Of INavigationService)(Me, "NavigationStart", False, AddressOf HandleParentChildNavigate)

これはNavigationServiceクラスを受け取り、この質問に関係のない他のロジックに基づいてチェックを実行します。

このメッセージは、NavigationServiceクラスで次のようにナビゲーションイベントがトリガーされたときに送信されます。

''Send message that navigation has been requested
Messenger.Default.Send(Of INavigationService)(Me, "NavigationStart")

これにより、受信クラス(この場合はClientListViewModel)にデータ検証エラーがある場合にナビゲーションイベントをキャンセルでき、エラーのあるレコードにフォーカスが戻ります。これはすべてうまくいきます。

私の質問は、どこでどのようにメッセージの登録を解除するかです。他の投稿を読んでいるときにメモリリークを回避するために必要なことはわかっています。私は次のようなものを見ました:

Public Overrides Sub CleanUp()
    Messenger.Default.Unregister(Me)
End Sub

このクリーンアップは、メッセージを受信するのと同じビューモデル(CientListViewModel)にあります。

だから私は3つの質問があります:

  1. このクリーンアップメソッドはいつ呼び出す必要がありますか

  2. ViewModelLocatorを使用して、アプリケーションが閉じられたときにすべてのメッセージ受信者の登録を解除する方法はありますか?

  3. この質問はあまり関連性がありませんが、助けていただければ幸いです。未登録のメッセージ受信者の結果として「メモリリーク」が発生しているかどうかを確認するにはどうすればよいですか。

御時間ありがとうございます

4

2 に答える 2

4

ビューモデルをいつ「クリーンアップ」する必要があるかは、アプリケーションとビューモデルの使用法によって異なります。たとえば、タブ付きのインターフェイスを使用したアプリケーションに取り組んでいます。ユーザーがタブを閉じると、アプリケーションはそのタブを表すビューモデルでクリーンアップを呼び出します(ビューモデル自体がビューモデルを通過し、ビューモデルでもクリーンアップを呼び出します)。したがって、一般的なルール-viewmodelが不要になったらすぐに-クリーンアップする必要があります(子ウィンドウ、タブなどを閉じる)。その他の質問については、次のようになります。

2)ビューモデルをクリーンアップする場合、アプリケーションを閉じることは実際には問題ではありません。閉じるとすべてのメモリが解放され、メモリリークが発生しなくなります:)

3)アプリケーションのメモリ使用量を確認する必要があります。私たちのアプリケーションでは、メモリリークに関して深刻な問題が発生しました(実際にはまだ発生していますが、それほど大きくはありません)メモリ追跡によってリークが発生する可能性があると判断しました。多くのタブを開いたり閉じGC.Collect()たりしましたが、メモリ使用量は減少しませんでした。WinDbgを使用してメモリリークの追跡を開始し、Messengerから受信者の登録を解除しなかった場所を文字通りたくさん見つけました。また、CommandManagerにバインドされている古いバージョンのMVVM Lightを使用しているため、RelayCommandsにも問題がありました。

道徳は-後でそれを見つけて修正するのは苦痛になる可能性があるので、プログラミング中にリソースをクリーンアップすることを考える必要があります。

于 2013-02-05T09:03:38.570 に答える
1

私はMVVM-LightでMessengerを使用したことがないので、クリーンアップする固有の方法があるかどうかわかりません。これらの質問に対する一般的な回答は次のとおりです。

  1. メッセージについて知る必要がなくなったとき、またはビューモデルが不要になったときに、クリーンアップを実行する必要があります。ナビゲートがキャンセルされていない場合、ViewModelはナビゲートメッセージを気にしませんか(つまり、アンロードされているのか、サポートしているビューが消えているのか)?その場合は、[ナビゲート]コマンドを受信し、ナビゲートしても問題ないと判断したときに登録を解除できます。

  2. これはわかりません。ただし、アプリを閉じるときは問題になりません(管理対象オブジェクトについては、以下を参照してください)。

  3. アプリのシャットダウン時に管理対象オブジェクトでこれらのメモリリークが発生することを心配する必要はありません。アプリドメイン全体が終了すると、参照されていないオブジェクトはすべて破棄されます。管理されていないリソースが参照されている場合、これは別の話です。

于 2013-02-01T17:56:58.277 に答える