0

私はwinformアプリケーションを持っています。メインフォームはシングルトンで、たくさんの画像をロードします。画像は製品を表し、画像をクリックするたびに、製品の在庫を変更し、製品と画像のハッシュテーブルをリロードします。

この問題は、BBDD から製品のハッシュテーブルをリロードして画像をリロードするたびに発生します。結局のところ、アプリケーションは大量のメモリを消費し、リロードするためにいつ、どのようにイメージをアンロードすればよいかわかりません (イメージを変更できて、リロードしなければならない場合があるため)。

ハッシュテーブルとボタンをリロードするコードは次のとおりです。

Family fam = new Family();

List<Family> listFamilies = fam.loadFamilies();
htProducts.Clear();

foreach(Family family in listFamilies)
{
   //reload all the products of each family
   if(htProducts[family.idFamily]==null)
   {
     List<Product> listProducts= fam.loadProductsFamily(family.idFamily);
     htProducts[family.idFamily] = listProducts;
   }
   Button bt = new Button();
   bt.location = new Point(x,y); //The buttons are created dinamically
   bt.Parent = panelFamilies;//I have all the buttons inside a panel.
   try
   {
      if(family.urlImage !="")
      {
         bt.Text=family.Name;
         bt.Image = new Bitmap(family.urlImage);
      }
   }
   catch(Exception ex)
   {
     ....
    }

}

ファミリ ボタンをクリックすると、そのファミリの製品が読み込まれますが、コードはほぼ同じです。また、画像もロードします。

多かれ少なかれこれがコードです。問題は、ボタンをクリックするたびに、製品と画像をロードするボタンをさらにロードすることです。

多くの場合、シングルトン フォームをリロードして前のコードを実行し、イメージを再度ロードしてメモリを消費します。

¿いつ、どのように画像をアンロードする必要がありますか?

編集:

画像付きのボタンを再度読み込む前に、次のコードを追加しました。

foreach (Control c in panel8.Controls)
{
    if (c is Button)
        c.Dispose();
}
GC.Collect(GC.MaxGeneration);// I think that isn't correct to use because I've read,  but reduces the memory.

パネルのすべてのボタンと画像を破棄し、画像を再度ロードする前にメモリを減らしますか?

ところで私の英語でごめんなさい:(

どうもありがとう。

4

3 に答える 3

2
foreach (Control c in panel8.Controls)
{
    if (c is Button)
        c.Dispose();
}

それはうまくいきません。一般に、.NETコレクションクラスは、コレクションを反復するforeachステートメントでコレクションを変更すると、InvalidOperationExceptionを発生させます。残念ながら、これはControlsコレクションには実装されていません。したがって、このコードが行うことは、他のすべてのコントロールを破棄することだけです。これは、ボタンコントロールだけでなく、それらの画像も含めて、制御されていないリソースリークを引き起こすのに十分です。

修正は、次のようにControlsコレクションを逆方向に繰り返すことです。

for (int ix = panel8.Controls.Count - 1; ix >= 0; --ix) {
    Control c = panel8.Controls[ix];
    // etc...
}
于 2012-08-27T23:21:13.113 に答える
1

フォームの参照を1つか2つ保持しているようです。

CLRProfilerやANTなどのデバッガーを使用してプロセスを調べ、プロセスで非常に多くのメモリを消費しているものを理解する必要があります。この情報を入手したら、収集できるように、その情報へのすべての参照を解放していることを確認する次のステップに進むことができます。

于 2012-08-27T21:41:27.990 に答える
1

トラブルシューティングするには、電話してください

GC.Collect(GC.MaxGeneration);

これにより、ガベージ コレクションが強制されます。次に、プロセス エクスプローラーまたはタスク マネージャーでメモリ使用量を確認します。小さい場合は、ランタイムがメモリを収集しないことを決定したことを意味するだけです。

うまくいかない場合は、メモリ リークを見つける必要があります。

于 2012-08-27T21:49:40.853 に答える