并行调用Graphics.Draw和线程内存中的新Bitmap需要很长时间

时间:2009-10-20 15:20:21

标签: c# multithreading image-processing

示例1 public partial class Form1 : Form {

    public Form1()
    {

        InitializeComponent();
    pro = new Thread(new ThreadStart(Producer));
    con = new Thread(new ThreadStart(Consumer));
    }
    private AutoResetEvent m_DataAvailableEvent = new AutoResetEvent(false);
    Queue<Bitmap> queue = new Queue<Bitmap>();
    Thread pro;
    Thread con ;

    public void Producer()
    {
        MemoryStream[] ms = new MemoryStream[3];
        for (int y = 0; y < 3; y++)
        {
            StreamReader reader = new StreamReader("image"+(y+1)+".JPG");
            BinaryReader breader = new BinaryReader(reader.BaseStream);

            byte[] buffer=new byte[reader.BaseStream.Length];
            breader.Read(buffer,0,buffer.Length);
            ms[y] = new MemoryStream(buffer);
        }
        while (true)
        {
            for (int x = 0; x < 3; x++)
            {
                Bitmap bmp = new Bitmap(ms[x]);
                queue.Enqueue(bmp);

                m_DataAvailableEvent.Set();
                Thread.Sleep(6);
            }
        }
    }
    public void Consumer()
    {
        Graphics g= pictureBox1.CreateGraphics();
        while (true)
        {
            m_DataAvailableEvent.WaitOne();
            Bitmap bmp = queue.Dequeue();
            if (bmp != null)
            {
              //  Bitmap bmp = new Bitmap(ms);
                g.DrawImage(bmp,new Point(0,0));
                bmp.Dispose();

            }
        }

    }
    private void pictureBox1_Click(object sender, EventArgs e)
    {

        con.Start();
        pro.Start();

    }
}

public Form1() { InitializeComponent(); pro = new Thread(new ThreadStart(Producer)); con = new Thread(new ThreadStart(Consumer)); } private AutoResetEvent m_DataAvailableEvent = new AutoResetEvent(false); Queue<Bitmap> queue = new Queue<Bitmap>(); Thread pro; Thread con ; public void Producer() { MemoryStream[] ms = new MemoryStream[3]; for (int y = 0; y < 3; y++) { StreamReader reader = new StreamReader("image"+(y+1)+".JPG"); BinaryReader breader = new BinaryReader(reader.BaseStream); byte[] buffer=new byte[reader.BaseStream.Length]; breader.Read(buffer,0,buffer.Length); ms[y] = new MemoryStream(buffer); } while (true) { for (int x = 0; x < 3; x++) { Bitmap bmp = new Bitmap(ms[x]); queue.Enqueue(bmp); m_DataAvailableEvent.Set(); Thread.Sleep(6); } } } public void Consumer() { Graphics g= pictureBox1.CreateGraphics(); while (true) { m_DataAvailableEvent.WaitOne(); Bitmap bmp = queue.Dequeue(); if (bmp != null) { // Bitmap bmp = new Bitmap(ms); g.DrawImage(bmp,new Point(0,0)); bmp.Dispose(); } } } private void pictureBox1_Click(object sender, EventArgs e) { con.Start(); pro.Start(); } } 当创建位图和绘图到图片框是在单独的线程中 然后位图bmp =新位图(ms [x])需要45.591毫秒 和g.DrawImage(bmp,new Point(0,0))需要41.430毫秒

当我从memoryStream创建位图并将其绘制到一个线程中的图片框时 位图bmp =新位图(ms [x])取29.619和g.DrawImage(bmp,新点(0,0))取35.540 代码是针对示例2的

为什么在单独的线程中花费更多时间绘制和位图花费时间以及如何减少在单独线程中处理时的时间。我正在使用ANTS性能分析器4.3

public Form1() {

        InitializeComponent();
    pro = new Thread(new ThreadStart(Producer));
    con = new Thread(new ThreadStart(Consumer));
    }
    private AutoResetEvent m_DataAvailableEvent = new AutoResetEvent(false);
    Queue<MemoryStream> queue = new Queue<MemoryStream>();
    Thread pro;
    Thread con ;

    public void Producer()
    {
        MemoryStream[] ms = new MemoryStream[3];
        for (int y = 0; y < 3; y++)
        {
            StreamReader reader = new StreamReader("image"+(y+1)+".JPG");
            BinaryReader breader = new BinaryReader(reader.BaseStream);

            byte[] buffer=new byte[reader.BaseStream.Length];
            breader.Read(buffer,0,buffer.Length);
            ms[y] = new MemoryStream(buffer);
        }
        while (true)
        {
            for (int x = 0; x < 3; x++)
            {
               // Bitmap bmp = new Bitmap(ms[x]);
                queue.Enqueue(ms[x]);

                m_DataAvailableEvent.Set();
                Thread.Sleep(6);
            }
        }
    }
    public void Consumer()
    {
        Graphics g= pictureBox1.CreateGraphics();
        while (true)
        {
            m_DataAvailableEvent.WaitOne();
            //Bitmap bmp = queue.Dequeue();
            MemoryStream ms= queue.Dequeue();
            if (ms != null)
            {
                Bitmap bmp = new Bitmap(ms);
                g.DrawImage(bmp,new Point(0,0));
                bmp.Dispose();

            }
        }

    }
    private void pictureBox1_Click(object sender, EventArgs e)
    {

        con.Start();
        pro.Start();

    }

1 个答案:

答案 0 :(得分:0)

所有UI操作都应该在同一个线程上进行。实际上,如果您希望系统稳定,则必须在同一个线程上进行。我想你所看到的多线程代码性能较慢的证据就是这种不稳定性的证据。

一定要在单独的线程中加载图像,但要更新主线程中的UI。

如果您在Stack Overflow上搜索标记为[multithreading] [c#]的问题,您会看到许多其他问题与您的问题相同。

例如,请参阅herehere