投稿

9月, 2019の投稿を表示しています

WPF FrameがPageのインスタンスを保持してる件

イメージ
WPFでページ遷移を作る場合、XAMLでFrameコントロールを置いてナビゲーションするのが手っ取り早い。しかし今回はちょっとした罠に掛かってしまった。 ページ遷移でメモリリーク? なんか画面移動するたびにメモリが増えていく。まあPageのインスタンスをその都度newしてるので一時的には増えるが、そのうちGCされるだろう。そう思ってたがいつまでも減らない。試しにGC.Collect()してみても減らない。Page内で残ってる参照なども心当たりがない。はて。 犯人はナビゲーション機能 Frameコントロールにはナビゲーションの機能が付いている。NavigationUIVisibility="Visible"を付けると[戻る]とか[進む]のボタンが出てくる。 こういうやつ。見た目がいまいちだしあまり使われてる気はしない。しかしどうもこの[戻る][進む]機能のために、Frameは表示したインスタンスの参照を保持しているようだった。 これはNavigationUIを非表示にしてもやめないし、履歴保持数などのプロパティも設定できない。いったいどの程度持ち続けるのだろうか。まさかメモリが枯渇するまで残し続けることは無いと信じたいが。 対策 前述の通りプロパティなどで無効化することはできないので、履歴を手で消してやる。以下のようなコードをどこかしらに実装する。 while (Frame.CanGoBack) { Frame.RemoveBackEntry(); } RemoveBackEntry()は最後の履歴を1件削除する。全クリアなどのメソッドは無いらしい。しかも履歴が一件も無い状態で呼ぶと例外が発生する。 これをページ遷移の処理部なりで呼んでやれば、とりあえず延々増えてくことは回避できる。確実なのはFrameの遷移完了イベントあたりか。 しかしAddなんちゃらみたいなメソッドではなく、Content=~という代入でキューイングされるのはちょっとイマイチな実装だと思う。