4

.netアプリケーションでListViewにImageListを使用する際に問題が発生します。私の実装では、このImageListは、用途に応じて数千の画像を保持できます。この問題は、元々、多数の画像を処理しようとしたときに発生しました。5K以上の画像を取得すると、画像を追加しようとして、一般的な「画像をImageListに追加できません」という例外が発生しました。この障害が発生した正確な数は少し跳ね上がりました。

そのため、この問題を解決するために、ネイティブのImageList_SetImageCount関数を使用してImageListの容量を拡張しようとしました。それは大丈夫で、私の当面の問題を解決しました。.Add()メソッドの代わりにImageList [index]=imageを使用してリストにデータを入力する必要がありました。これはすべて問題ありませんでしたが、画像を引き出すときに問題が発生しました。これで、そのImageList内の画像をインデックスで参照すると、メモリ不足例外が発生します。Bitmap x =ImageList[任意のインデックス]がクラッシュします。

私はこれをさまざまな方法で追跡しようとしましたが、ImageListでまだ問題が発生しています。

この問題をさらに調査する最後の試みでは、まだ奇妙な動作をしている次のテストコードをまとめました。

    private void Form1_Load(object sender, EventArgs e)
    {
        list = new ImageList();
        list.ImageSize = new Size(128, 128);
        list.ColorDepth = ColorDepth.Depth32Bit;
        Image[] images = new Image[10];
        for (int y = 0; y < 10; y++)
        {
            images[y] = new Bitmap(@"Path to loading_photo.png");
        }
        for (int x = 0; x < 750; x++)
        {
            list.Images.AddRange(images);
        }

        list.Images[12] = new Bitmap(@"Path to another.png");

最後の行は「画像をImageListに追加できません」というエラーでクラッシュします。奇妙なことに、2番目のループをより低い反復(つまり、合計2000の画像が追加される場合は200)に設定すると、正常に動作します。

私が知らない.netのImageListに特定のしきい値はありますか?どんな助けでも大歓迎です。

4

2 に答える 2

3

投稿されたコードでは再現性がまったく得られません。ただし、ImageList はビットマップのコピーを作成することに注意してください。したがって、ビットマップを追加した後、ビットマップの Dispose() メソッドを呼び出す必要があります。そうしないと、管理されていないメモリが不足し、ビットマップ データによって消費され、後でクリーンアップするのに十分な頻度でガベージ コレクタが実行されない場合に致命的となるという深刻なリスクがあります。ビットマップは 10 個しかないため、これはスニペットには適用されません。

于 2012-04-17T00:30:06.217 に答える
0

リフレクターを使用してコードの最後の行が何をするかを調べると、ImageListのセッターが実際にこの行で失敗していることがわかります。

bool flag2 = SafeNativeMethods.ImageList_Replace(new HandleRef(this.owner, this.owner.Handle), index, new HandleRef(null, handle), new HandleRef(null, monochromeMask));

これには、Windowsで制限されているハンドルの操作が含まれます(正しく思い出せば、プロセスごとに10000)。したがって、空きメモリはたくさんありますが、おそらくハンドルの制限に達しています。

于 2012-04-16T20:46:34.653 に答える