比较列表项时,为什么我会出现内存异常?

时间:2015-01-29 17:39:41

标签: c# .net winforms

在绘画事件中,我绘制一个矩形,然后将矩形区域内的像素坐标添加到List:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (cloudPoints != null)
            {
                if (DrawIt)
                {
                    e.Graphics.DrawRectangle(pen, rect);
                    pointsAffected = cloudPoints.Where(pt => rect.Contains(pt));

                    CloudEnteringAlert.pointtocolorinrectangle = pointsAffected.ToList();
                    Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height, PixelFormat.Format32bppArgb);
                    CloudEnteringAlert.Paint(e.Graphics, 1, 200, bmp);
                }
            }   
        }

我正在绘制一个矩形,其中包含rect(Rectangle)变量并指定pointsAffected列出的只是rect区域内的像素坐标! cloudPoints包含整个图像的所有像素坐标!但pointsAffected仅包含矩形区域内的像素坐标。

然后鼠标向上事件:

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            StreamWriter w = new StreamWriter(@"c:\diff\diff.txt");
            pixelscoordinatesinrectangle = new List<Point>();
            pixelscoordinatesinrectangle = pointsAffected.ToList();
            DrawIt = false;
            for (int i = 0; i < trackBar1FileInfo.Length; i++)
            {
                DrawIt = true;
                trackBar1.Value = i;
                LoadPictureAt(trackBar1.Value, sender);
                pictureBox1.Load(trackBar1FileInfo[i].FullName);
                ConvertedBmp = ConvertTo24(trackBar1FileInfo[trackBar1.Value].FullName);
                ConvertedBmp.Save(ConvertedBmpDir + "\\ConvertedBmp.bmp");
                mymem = ToStream(ConvertedBmp, ImageFormat.Bmp);
                backTexture = TextureLoader.FromStream(D3Ddev, mymem);
                scannedCloudsTexture = new Texture(D3Ddev, 512, 512, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
                Button1Code();
                pictureBox1.Refresh();
                newpixelscoordinates = new List<Point>();
                newpixelscoordinates = pointsAffected.ToList();
                if (pixelscoordinatesinrectangle != null && newpixelscoordinates != null)
                {
                    IEnumerable<Point> differenceQuery =
                    pixelscoordinatesinrectangle.Except(newpixelscoordinates);

                    // Execute the query.
                    foreach (Point s in differenceQuery)
                        w.WriteLine("The following points are not the same" + s);
                }
                else
                {
                    am1 = pixelscoordinatesinrectangle.Count;
                    am2 = newpixelscoordinates.Count;
                }
                //MessageBox.Show(pixelscoordinatesinrectangle.Count.ToString());
            }
            w.Close();
        }

在完成绘制后绘制矩形时,我正在创建一个新的List实例,并将像素存储在pixelscoordinatesinrectangle列表的矩形区域中。

然后我循环遍历trackBar1FileInfo,其中包含来自硬盘的5000个图像文件名。

这是问题部分:

pictureBox1.Refresh();
                newpixelscoordinates = new List<Point>();
                newpixelscoordinates = pointsAffected.ToList();
                if (pixelscoordinatesinrectangle != null && newpixelscoordinates != null)
                {
                    IEnumerable<Point> differenceQuery =
                    pixelscoordinatesinrectangle.Except(newpixelscoordinates);

                    // Execute the query.
                    foreach (Point s in differenceQuery)
                        w.WriteLine("The following points are not the same" + s);
                }
                else
                {
                    am1 = pixelscoordinatesinrectangle.Count;
                    am2 = newpixelscoordinates.Count;
                }

我正在对pict​​ureBox1进行刷新,因此它会将每个图像转换为一个paint事件,并创建一个新的List,每次使用不同的像素坐标时,每次都会有不同的像素坐标。

所以newpixelscoordinates应该使用新的像素坐标每个循环迭代。

然后我将两个列表newpixelscoordinates和pixelscoordinatesinrectangle比较为不同的项目。

并将那些不同的人写入文本文件。

所以我得到一个非常大的文本文件,其中许多像素坐标在两个列表中都不相同。

问题是:

  1. 我做的比较是对的吗?我想比较一个列表索引与其他listi ndex。

    例如,在索引0中的列表newpixelscoordinates中,如果我有x = 233 y = 23并且在索引0中的列表pixelscoordinatesinrectangle中有x = 1 y = 100,则将其写为与文本文件不同。 / p>

    我想要做的是检查整个列表项目与其他列表项目,如果某些项目不相同,请将此项目写入文本文件。

  2. 下一次迭代新图像新列表与新像素坐标进行相同的比较。

    List pixelscoordinatesinrectangle没有改变它在我第一次绘制矩形时存储第一个像素坐标。每次只更改List newpixelscoordinates,应更改每次迭代。

    1. 我得到的例外就是:

      newpixelscoordinates = new List();

    2. 我添加了这一行,因为我想我可能每次都没有清除它,但它没有帮助。

      在添加此行之前,异常就行了:

      newpixelscoordinates = pointsAffected.ToList();
      

      异常是:OutOfMemoryException:内存不足

      System.OutOfMemoryException was unhandled
        HResult=-2147024882
        Message=Out of memory.
        Source=System.Drawing
        StackTrace:
             at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
             at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
             at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
             at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
             at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
             at System.Windows.Forms.Control.WmPaint(Message& m)
             at System.Windows.Forms.Control.WndProc(Message& m)
             at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
             at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
             at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
        InnerException: 
      

1 个答案:

答案 0 :(得分:1)

在您的代码中,必须释放一些对象来释放内存,例如Bitmap中的pictureBox1_Paint对象,StreamWriter中的pictureBox1_MouseUp对象。可能还有更多。

对于实现IDisposable接口的托管对象 ,你必须处理它们以及时释放未管理的内存。 GC特别不是为了管理非托管资源而设计的,非管理内存的使用不会增加GC压力并且不会触发GC动作,这就是你出现内存异常的原因。

使用代码分析编译您的编程,它将告知哪些对象需要在警告中处理。将它们放在using区块中。