C#在多线程中将面板保存为图像

时间:2018-03-22 16:30:27

标签: c# multithreading image panel

我没有任何问题将面板保存为带有UI线程的图像,但是当我将此面板保存在除UI线程之外的另一个线程时,我只有一个黑色矩形:

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);
            }

        }

这个问题与锁定机制有关?或者我该如何解决这个问题?

提前致谢。

1 个答案:

答案 0 :(得分:3)

通用答案(附说明)

BeginInvoke是发送消息的函数'此函数应该在不同的线程中执行',然后直接离开以继续在当前线程中执行。

当目标线程具有“空闲时间”(处理之前发布的消息)时,该函数将在稍后执行。

当您需要该功能的结果时,请使用InvokeInvoke函数“慢”,或更好地说它阻止当前线程,直到执行的函数完成。 (我刚刚在C#中对此进行了测试,但有可能Invoke函数优先;例如当您调用BeginInvoke并且直接在Invoke之后调用同一个线程时,Invoke中的函数可能会在BeginInvoke的函数之前执行。)

当您需要在处理下一条指令之前执行该函数(当您需要调用函数的结果时)时,请使用此替代方法。

简单(tl; dr) :当您需要只设置值(例如设置编辑框文本)时,使用BeginInvoke,但是当您需要结果时(例如从编辑框中获取文字)始终使用Invoke

在您的情况下,您需要结果(要绘制的位图)因此您需要等待函数结束。 (还有其他可能的选项,但在这种情况下,简单的方法是更好的方法。)