2011-07-08 15 views
7

サムネイルイメージを多数(時には何百もの場合もある)読み込む必要があります。パフォーマンス上の理由から、私は限られた数のリクエストでこれを行う必要があります。私はテストのために単一のリクエスト/レスポンスを使用しています。私はレスポンスの画像のバイナリデータを送信し、MemoryStreamを使ってBitmapImageにロードしています。これは、約80枚以上のサムネイルを読み込むまで正しく動作します。その後、致命的なエラー例外が発生します。私のデータが壊れていないことを確認するために、私は同じバイト配列でBitmapImageを複数回ロードしようとしましたが、80またはそれ以降のロードでクラッシュしました。私はその後のソースとしてのBitmapImageを使用Silverlight:ストリームからのビットマップイメージ例外(致命的なエラー(HRESULT:0x8000FFFF(E_UNEXPECTED)からの例外))

private BitmapImage LoadImage(byte[] imageData) 
{ 
    BitmapImage img = new BitmapImage(); 
    MemoryStream stream = new MemoryStream(imageData); 
    img.SetSource(stream); // Exception thrown here after too many images loaded. 
    return img; 
} 

:ここ

画像をバイト配列からロードする方法のサンプルであり、バイト配列は、有効な画像データ(PNG)を有することが知られていますページの画像要素ですが、上記の img.SetSource(...)行でエラーが発生します。

ループにサムネイル画像をロードしているときに、画像をもう少し読み込むことができるので、これはメモリ管理と関係がありますが、問題を解決するために何ができるか分かりません。

+0

これが問題になる可能性があるのか​​どうかはわかりませんが、MemoryStreamにはReadTimeoutプロパティとWriteTimeoutプロパティがあります。ストリームがタイムアウトになることはありますか? – Danexxtone

+0

ReadTimeoutを設定しようとしましたが、例外があります。このストリームではタイムアウトはサポートされていません。 – toby

+0

いくつかの問題を解決できますか?なぜバイト配列ですか? 'img.SetSource'に直接ダウンロードできるストリームはありませんか?ダウンロードしているPNGが「サムネイル」サイズであるか、画像コントロールで拡大縮小されている大きな画像をダウンロードしていますか?写真のサムネイルはありますか? – AnthonyWJones

答えて

6

私はそれが非常に簡潔で、問題の記述だけでなく、推奨されるソリューション提供であるため、上記のバグレポートにMicrosoftが提供する答えを引用することは価値があると思う:、Silverlightがイメージをロードするとき

をフレームワークは、フロー制御がUIスレッドディスパッチャに返されるまで、参照を保持し、復号化された画像をキャッシュする。このようなタイトなループで画像を読み込むと、アプリケーションに参照が保持されなくても、フロー制御が返されたときに参照を解放するまで、GCは画像を解放できません。

20以上のイメージを処理した後、Dispatcher.BeginInvokeを使用して次のセットを停止してキューに入れるだけで、1つのバッチで処理される作業を分割できます。これにより、アプリケーションによって保持されていないイメージを解放することができます。

Silverlightがこれらの参照を保持していることは明らかではありませんが、デコーダのデザインを変更すると他の領域に影響する可能性があるので、今のようにバッチで処理することをおすすめします。

実際に500枚の画像を読み込んで保持しようとすると、画像のサイズによってはメモリが不足する可能性があります。複数ページのドキュメントを扱う場合は、必要に応じてバックグラウンドでページをロードし、数ページのバッファで表示が外になったら解放して、妥当なテクスチャメモリの制限を超えないようにすることができます。

関連する問題