簡體   English   中英

嘗試在pictureBox中播放圖像時,為什么會出現內存不足異常?

[英]Why getting out of memory exception when trying to play images in pictureBox?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Player_Manager
{
    public partial class ScreenShotsPlayer : Form
    {
        FileInfo[] images;
        DirectoryInfo di1;
        int current = 0;

        public ScreenShotsPlayer()
        {
            InitializeComponent();

            di1 = new DirectoryInfo(@"e:\screenshots");
            images = di1.GetFiles("*.bmp");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            current = (current >= images.Length - 1) ? 0 : ++current;
            pictureBox1.Image = new Bitmap(images[current].FullName);
            pictureBox1.Refresh();
        }
    }
}

硬盤上有1200張圖像,並且計時器設置為100ms。 播放約258-270張圖像后,它會在行上拋出內存不足異常:

pictureBox1.Refresh();

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: 

如果我將刪除那行pictureBox1.Refresh(); 然后它將引發以下異常:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Player_Manager
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

在線Application.Run(new Form1());

同樣的例外。

GDI +的好處在於,它所使用的內存沒有得到管理-GC不知道您浪費了多少觸發一個收集,因此它只會不斷堆積直到GDI +用完可分配內存。

該修復程序非常簡單。 您知道要分配的位圖,只需在不再需要它們時就將其丟棄:

    private void timer1_Tick(object sender, EventArgs e)
    {
        if(pictureBox1.Image!=null)
        {
            var img = pictureBox1.Image;  // cache it to dispose
            pictureBox1.Image = null;     // don't dispose an used object
            img.Dispose();                // and dispose of it
        }

        current = (current >= images.Length - 1) ? 0 : ++current;
        pictureBox1.Image = new Bitmap(images[current].FullName);
        pictureBox1.Refresh();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM