質問

私はC#でニュービーです。私は繰り返しワーカースレッドでGUIのピクチャボックスをリフレッシュする必要があります。画像を表示する画像をretrivesのgetImageメソッドとカメラポーリングドライバから取得されます。私は「使用」ディレクティブを使用してビットマップを割り当て、明示的G.Cを呼び出す場合でも、メモリの割り当てが解除されませんしているようです。

ワーカースレッドは次のようなものです。

   while (true)
    {
        // request image with IR signal values (array of UInt16)
        image = axLVCam.GetImage(0);
        lut = axLVCam.GetLUT(1);
        DrawPicture(image, lut);
        //GC.Collect();

    }

DrawPictureメソッドは、

のようなものですが
   public void DrawPicture(object image, object lut)
{

  [...]

    // We have an image - cast it to proper type
    System.UInt16[,] im = image as System.UInt16[,];
    float[] lutTempConversion = lut as float[];

    int lngWidthIrImage = im.GetLength(0);
    int lngHeightIrImage = im.GetLength(1);

    using (Bitmap bmp = new Bitmap(lngWidthIrImage, lngHeightIrImage)) {

      [...many operation on bitmap pixel...]

        // Bitmap is ready - update image control

        //SetControlPropertyThreadSafe(tempTxtBox, "Text", string.Format("{0:0.#}", lutTempConversion[im[160, 100]]));

        //tempTxtBox.Text = string.Format("{0:00000}", im[160, 100]);
        //System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
        pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
    }
}

問題が発生すると、

  

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

コード行をコメント実際には、ガベージコレクションは、それが同じように動作します。 より良い、問題がとのようです。

  

System.Drawing.Image.FromHbitmap(bmp.GetHbitmap())

このメモリリークを解決するための任意のアドバイスはありますか?

どうもありがとうございました!

役に立ちましたか?

解決

ImageIDisposableを実装し、それが不要になったとき、あなたは、あなたが作成した各Disposeインスタンス上Imageを呼び出すべきではありません。あなたはあなたのコードでは、この行を置き換えるために試みることができる:

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

これによります:

if (pic.Image != null)
{
    pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

この新しいものが割り当てられる前に前の画像を(もしあれば)処分されます。

他のヒント

の事はあなたがGetHbitmap、MSDNによるとbmpのGDIビットマップを作っている、あります

  

あなたが呼び出すための責任があります   GDI DeleteObjectの解放する方法   GDIビットマップオブジェクトが使用するメモリます。

次にFromHbitmap方法は、GDIビットマップのコピーを作成します。あなたはすぐに新しいイメージを作成した後、GDI DeleteObjectの方法を使用して着信GDIビットマップを解放することができます。

だから、基本的に私が追加することになります:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

IntPtr gdiBitmap = bmp.GetHbitmap();

// Release the copied GDI bitmap
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = System.Drawing.Image.FromHbitmap(gdiBitmap);

// Release the current GDI bitmap
DeleteObject(gdiBitmap);
あなたはある種の変換を実行するためにGDIビットマップが必要な場合は、

私はわかりませんよ。場合は、あなたがちょうどあなたのPictureBoxのImageプロパティにビットマップを割り当て、かつてのソリューションを無視することができません。

// Since we're not using unmanaged resources anymore, explicitly disposing 
// the Image only results in more immediate garbage collection, there wouldn't 
// actually be a memory leak if you forget to dispose.
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = bmp;

PBOXから画像を解放するには、いくつかの方法があります。私は強く方法はpbox.Image = Image.FromFile...を使用していないということですお勧めします。あなたは、FileStreamをを使用していない、あなたはファイル使用Bitmapクラスからそれを読みたい場合。このように:

Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.

...そして、あなたは、画像ファイルbmp.Dispose();
をリリースしたいです 今、あなたは、削除、移動したり、ファイルに好きなことができます。

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