Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
806 views
in Technique[技术] by (71.8m points)

multithreading - C# Saving Panel as image at Multithread

I don't have any problem saving panel as image with UI thread but i have only a black rectangle when i save this panel at another thread except UI thread :

using (Bitmap bmp = new Bitmap(panel1.Width, panel1.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
        {
            if (panel1.InvokeRequired)
            {
                panel1.BeginInvoke((MethodInvoker)delegate ()
                {
                    panel1.DrawToBitmap(bmp, new System.Drawing.Rectangle(Point.Empty, bmp.Size));

                });
                Bitmap bb = bmp.Clone(new System.Drawing.Rectangle(0, 0, 1016, 648), PixelFormat.Format24bppRgb);
                bb.Save(@"C:sample.bmp", ImageFormat.Bmp);
            }
            else
            {
              panel1.DrawToBitmap(bmp, new System.Drawing.Rectangle(Point.Empty, bmp.Size));
              Bitmap bb = bmp.Clone(new System.Drawing.Rectangle(0, 0, 1016, 648), PixelFormat.Format24bppRgb);
              bb.Save(@"C:sample.bmp", ImageFormat.Bmp);
            }

        }

This problem is related with locking mechanism? Or how can i solve this problem?

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Universal answer (with explanation):

BeginInvoke is function that send a message 'this function should be executed in different thread' and then directly leaves to continue execution in current thread.

The function is executed at a later time, when the target thread has 'free time' (messages posted before are processed).

When you need the result of the function, use Invoke. The Invoke function is 'slower', or better to say it blocks current thread until the executed function finishes. (I newer really tested this in C#, but it s possible, that the Invoke function is prioritized; e.g. when you call BeginInvoke and directly after it Invoke to the same thread, the function from Invoke will probably be executed before the function from BeginInvoke.)

Use this alternative when you need the function to be executed before the next instruction are processed (when you need the result of the invoked function).

Simple (tl;dr): When you need to need to only set a value (e.g. set text of edit box), use BeginInvoke, but when you need a result (e.g. get text from edit box) use always Invoke.

In your case you need the result (bitmap to be drawn) therefore you need to wait for the function to end. (There are also other possible options, but in this case the simple way is the better way.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...