我没有任何问题将面板保存为带有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);
}
}
这个问题与锁定机制有关?或者我该如何解决这个问题?
提前致谢。
答案 0 :(得分:3)
通用答案(附说明):
BeginInvoke
是发送消息的函数'此函数应该在不同的线程中执行',然后直接离开以继续在当前线程中执行。
当目标线程具有“空闲时间”(处理之前发布的消息)时,该函数将在稍后执行。
当您需要该功能的结果时,请使用Invoke
。 Invoke
函数“慢”,或更好地说它阻止当前线程,直到执行的函数完成。 (我刚刚在C#中对此进行了测试,但有可能Invoke
函数优先;例如当您调用BeginInvoke
并且直接在Invoke
之后调用同一个线程时,Invoke
中的函数可能会在BeginInvoke
的函数之前执行。)
当您需要在处理下一条指令之前执行该函数(当您需要调用函数的结果时)时,请使用此替代方法。
简单(tl; dr) :当您需要只设置值(例如设置编辑框文本)时,使用BeginInvoke
,但是当您需要结果时(例如从编辑框中获取文字)始终使用Invoke
。
在您的情况下,您需要结果(要绘制的位图)因此您需要等待函数结束。 (还有其他可能的选项,但在这种情况下,简单的方法是更好的方法。)