C# Threading Bitmap objects/PictureBox

烈酒焚心 提交于 2019-12-08 08:06:14

问题


I have some code to display video-like graphics of points moving around.

I am writing the points to a bitmap, and placing it on a picturebox.

The graphics computation has to be done on its own thread. The graphics work fine as long as you don't move the window around "too" much.

I'm using winforms. When I run the code, and move the window around wildly, I SOMETIMES get the following errors:

@ this.Invoke(d, new object[ ] { bmp }); "Cannot access a disposed object. Object name: 'Form1'."

@ gfx.DrawImage(bmpDestination, new Point()); "Object is currently in use elsewhere."

Here is the code:

private void button2_Click(object sender, EventArgs e)
        {
            Thread demoThread = new Thread(new ThreadStart(ThreadProcSafe));

            demoThread.Start();
        }

        private void ThreadProcSafe()
        {
            creategraphics();
        }

        private void creategraphics()
        {

                Bitmap bmpDestination = new Bitmap(988, 588);
                Bitmap bmp = new Bitmap(988, 588);


                for (int i = 0; i < numtimesteps; i++)
                {
                    bmp = GraphingUtility.create(apple, i, 988, 588, -30, 30, -30, 30);

                        using (Graphics gfx = Graphics.FromImage(bmp))
                        {
                            gfx.DrawImage(bmpDestination, new Point());
                        }
                        bmpDestination = bmp;
                        updateimage(bmp);
                }
        }

        delegate void graphicscallback(Bitmap bmp);

        private void updateimage(Bitmap bmp)
        {
                if (pictureBox1.InvokeRequired)
                { 
                   graphicscallback d = new graphicscallback(updateimage);
                   this.Invoke(d, new object[] { bmp });
                }
                else
                { 
                    pictureBox1.Image = bmp;
                    pictureBox1.Refresh();  
                }
        }

回答1:


There are problems using GDI objects across threads.

Look at Hans' double-clone suggestions in this thread.




回答2:


Cannot access a disposed object. Object name: 'Form1

You get this because you don't do anything to stop the thread when the user closes the form. You'll have to keep the form alive until you know that the thread is dead. Pretty hard to do reliable, check this answer for a solution.

As an aside, calling InvokeRequired is an anti-pattern. You know that you are making the call from a worker thread. If InvokeRequired would return false then there's something really wrong. Don't bother, call Invoke() directly.

Object is currently in use elsewhere

It is an exception raised by GDI+ (Graphics) when it sees that two threads are trying to access a bitmap at the same time. It isn't obvious in your snippet but I can't see what GraphingUtility.create() does. Make sure it creates a new bitmap, not return an existing one. Because that will bomb when your thread writes to it again and the picture box repaints itself at the same time. The bmp constructor you use above it doesn't do anything.

Your PictureBox.Image assignment is forgetting to dispose the old one.



来源:https://stackoverflow.com/questions/5438673/c-sharp-threading-bitmap-objects-picturebox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!