私の wp8 アプリの 1 つで、BindingReflector を使用してコンバーター パラメーターのバインディングを有効にしています。私が遭遇した 1 つの問題は、(XAML で) パラメーターのバインドを使用するコンバーターの上にあるコンバーターがまったく GC されないことです。この特定の順序付けを使用していたページは、そのページに移動してから戻って繰り返すと、ますます多くのメモリを取得することに気付きました。
何が起こっているのかを理解しようと何度も試みた後、XAMLでそれらの順序を変更して、一番上にあるリフレクターを使用して問題を解決することにしました。誰かがこれについて説明できるかどうか疑問に思っていました。
このメモリリークの問題が発生したとき、GC Rootsの下のプロファイラーは、すべてのコンバーターがハンドル (WeakRef)を持つリフレクターを使用してコンバーターを (直接ではなく) 参照していることを示していました。どうしてそうなったのかはわかりませんが、いったん怒鳴れば、すべてがうまくいき、GC が適切に行われます。
コンバーターはすべて兄弟コントロールにあることに注意してください。構造は基本的に次のようなリストボックスでした。
<ListBox ItemsSource={Binding...}>
<!-- ... item template like below -->
<controlX propX={Binding xxx, converter=....}/>
<controlY propY={Binding yyy, converter=....}/>
...
</ListBox>
編集:ここから zip をダウンロード できる簡単なテスト プロジェクトを作成してアップロードしました。アプリを実行し、MainPage が読み込まれたら、Page1.xaml に移動するボタンをクリックし、[戻る] ボタンをクリックして、Page1.xaml に移動するボタンをもう一度クリックし、このプロセスを繰り返します。
現在のメモリ使用量を示す各ページのタイトルの下にカウンターを含めました。そこには何も気付かないかもしれませんが、次の 3 つのカウンターは次のとおりです。
- Page1 オブジェクトの現在のインスタンス数 (黄色)
- ランダム コンバーター オブジェクトの現在のインスタンス数 (赤)
- バインディング リフレクタ オブジェクトを使用するコンバータの現在のインスタンス数 (緑)
MainPage.xaml と Page1.xaml の間を行ったり来たりすると、黄色と緑が 3 を超えることはありませんが、赤は増加し続けます。
ここで、Page1.xaml のコンバーターを使用して 2 つのボタン コントロールの位置を切り替えます。それらをコメント アウトし、その下にあるものをコメント解除するだけで、3 つすべてのカウンターが 3 を超えることはありません。
編集 2: どうやら、これはリフレクターをバインドするだけではありません。両方のボタンで同じコンバーターを使用すると、特定のコンバーター インスタンスが GC されません。なぜこれが起こっているのかわかりません..