質問

コンパクトフレームワークアプリケーションは、すべてのアイテムを大きなビットマップサーフェスにレンダリングし、そのビットマップを画面上のオフセット位置にコピーして、適切なアイテムのみが表示されるようにすることで、スムーズスクロールリストを作成します。古いバージョンでは、その時点で画面に表示されるアイテムのみがレンダリングされていましたが、このアプローチはスムーズなスクロールインターフェイスには遅すぎました。

大きなビットマップを最初に作成するときに、OutOfMemoryExceptionが生成されることがあります。ユーザーがデバイスのソフトリセットを実行し、アプリケーションを再度実行すると、問題なく作成を実行できます。

アプリケーションは、新しいスムーズスクロールメソッドの前とほぼ同じ量のプログラムメモリを使用するため、このビットマップがプログラムメモリで生成されているようには見えません。

この例外を防ぐ方法はありますか?例外がスローされる前に、必要なメモリを解放する方法はありますか(どこでも)。

役に立ちましたか?

解決

完全にレンダリングされたデータのサイズは明らかに問題であるため、データの一部のみをレンダリングする古いメカニズムに戻ることをお勧めします。レンダリングの問題を防ぐために、現在のビューの上下にいくつかの行を事前にレンダリングして、「スクロール」できるようにします。影響は限定的です。

他のヒント

そして、私が投稿したとたんに、新しいバージョンであなたの問題を解決するためにできることができると思いました。あなたが持っている問題は、巨大なビットマップのために利用可能な連続したメモリの1つのブロックを見つけようとしているCFの1つであり、これは時々問題です。

1つの大きなビットマップを作成する代わりに、アイテムごとに小さなビットマップのコレクションを作成し、各アイテムを独自の小さなビットマップにレンダリングできます。表示中に、必要なビットマップをコピーするだけです。 CFは、大きなビットマップよりも小さなビットマップの束を作成する方がはるかに簡単です。これが本当に膨大なアイテムでない限り、メモリの問題はないはずです。

「修正はありません」などの表現は避けるべきです。

もう1つの重要な点:ビットマップを使い終わったら、必ず各ビットマップでDispose()を呼び出してください。

あなたのビットマップは間違いなくプログラムメモリに作成されています 。ビットマップが必要とするメモリの量は、ビットマップの大きさに依存し、この必要なサイズがOutOfMemoryExceptionを生成するかどうかは、PDAで使用可能な量に依存します(これにより、ランダムに発生するエラーになります)。

申し訳ありませんが、これは通常、お勧めできないコントロールレンダリングテクニック(特にコンパクトフレームワーク)であり、PDAの物理メモリを増やす以外に修正方法はありません。通常は不可能です(多くの場合修正されません)とにかく、問題は、デバイスがどれだけ利用可能であってもCFプロセスが32MBに制限されているためです。

最善の策は、古いバージョンに戻ってレンダリング速度を改善することです。 CFには、フリッカーをなくすためにコントロールをダブルバッファリングするための簡単なテクニックもあります。

作成できるビットマップスペースの合計サイズを制限しているデバイスの制限に直面しているように見えるため(これらは明らかに一般的なプログラムメモリではなくビデオRAMに作成されます)、1つの選択肢は大きなビットマップオブジェクトを置き換えることですここでは、Windowsメモリの古くて古いブロックで使用され、BitBlt API関数を呼び出して読み取りと書き込みのためにアクセスします。

メモリブロックを最初に作成するのは難しいので、それについて別のSO質問をしたいと思うでしょう(GCHandle.Allocをここで使用して、「ピン留め」オブジェクトを作成できます。つまり、.NETは、メモリ内で移動します。これはここで重要です)私はそれを行う方法を知っていますが、私はそれを正しく行うかどうか確信が持てず、むしろ専門家の意見を聞きたいです。

大きなブロックを作成したら、アイテムを繰り返し処理し、それぞれを既存の.NETコードを使用して再利用し続ける小さなビットマップにレンダリングし、BitBltを適切な場所に配置しますメモリブロック。

キャッシュ全体を作成した後、レンダリングコードは以前と同じように機能するはずです。ただし、大きなビットマップからレンダリングサーフェスにコピーする代わりに、キャッシュブロックからBitBltを使用します。 BitBltの引数は、DrawImageの引数と本質的に同じです(宛先、ソース、座標、サイズなど)。

特殊なビデオRAMではなく、この方法で通常のメモリからキャッシュを作成しているため、同じ問題に遭遇することはないと思います。ただし、最初にブロック作成コードを確実に機能させ、毎回十分な大きさのブロックを作成できることを確認するためにテストします。

更新:実際、理想的なアプローチは、1つの大きなブロックではなく小さなメモリブロックのコレクションを持つことです(ビットマップアプローチの問題だと思っていたように)が、すでに十分です。 5 MBと10 MBのオブジェクトを処理するCFアプリを使用しましたが、とにかく大きな問題ではありません(ただし、そのチャンクが固定されている場合は大きな問題になる可能性があります-私は知らない)。ところで、ビットマップが利用可能なメモリよりもはるかに小さいことを知っていたので、私はいつもBitMap作成のOOMEに驚いていました-あなたは今、理由を知っています。申し訳ありませんが、これは最初は簡単に解決できると思いました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top