private void DrawMap()
{
UpdateUI("正在绘图,请等待……");
bmpDraw = new Bitmap(W, H); Graphics g = Graphics.FromImage(bmpDraw);
g.DrawImage(bmp, 0, 0); Font f = new Font("宋体", 12, FontStyle.Bold);
Brush b = new SolidBrush(Color.Black);
g.DrawString(string.Format("{0,8:f1}毫米", ar[0]), f, b, 20, 250);
……………………
f.Dispose(); b.Dispose();
g.Dispose(); UpdateUI("绘图完毕!"); bmpDraw.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
SaveImg();
} private void allWork()
{
DrawMap();
} // 切换回UI线程执行的入口
// 现在没问题了,使用Invoke使得线程总是回到UI线程,所以我们可以放心大胆地调用控件的成员了
private void UpdateUI(string str)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg1(UpdateUI),str);
}
else
{
toolStripStatusLabel1.Text = str;
}
}
private void SaveImg()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate();
}
} private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
Thread myThread = new Thread(new ThreadStart(allWork));
myThread.Start(); }
这样是没有问题的,但是如果稍微改变以下红色部分
private void DrawMap()
{
UpdateUI("正在绘图,请等待……");
bmpDraw = new Bitmap(W, H); Graphics g = Graphics.FromImage(bmpDraw);
g.DrawImage(bmp, 0, 0); Font f = new Font("宋体", 12, FontStyle.Bold);
Brush b = new SolidBrush(Color.Black);
g.DrawString(string.Format("{0,8:f1}毫米", ar[0]), f, b, 20, 250);
……………………
f.Dispose(); b.Dispose();
g.Dispose(); UpdateUI("绘图完毕!"); SaveImg();
bmpDraw.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
} private void allWork()
{
DrawMap();
} // 切换回UI线程执行的入口
// 现在没问题了,使用Invoke使得线程总是回到UI线程,所以我们可以放心大胆地调用控件的成员了
private void UpdateUI(string str)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg1(UpdateUI),str);
}
else
{
toolStripStatusLabel1.Text = str;
}
}
private void SaveImg()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate();
}
} private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
Thread myThread = new Thread(new ThreadStart(allWork));
myThread.Start(); }问题就出来了,编译通过,但是执行是提示:
未处理TargetInvocationException
InnerException:如果在使用GetHdc方法后使用Graphics对象,请调用ReleaseHdc方法
UpdateUI("绘图完毕!");
SaveImg(); private void SaveImg()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
bmpDraw.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate(); }
}
也是出错
但是改为这样的话又没问题: UpdateUI("绘图完毕!");
SaveImg(); private void SaveImg()
{
bmpDraw.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate();}
}给我的感觉就是调用了SaveImg()后把线程送到UI线程上去了,然后就出这种奇怪的问题出来了(我水平太低,不知怎么描述了)
private void DrawMap()
{
UpdateUI("正在绘图,请等待……");
bmpDraw = new Bitmap(W, H); Graphics g = Graphics.FromImage(bmpDraw);
g.DrawImage(bmp, 0, 0); Font f = new Font("宋体", 12, FontStyle.Bold);
Brush b = new SolidBrush(Color.Black);
g.DrawString(string.Format("{0,8:f1}毫米", ar[0]), f, b, 20, 250);
……………………
f.Dispose(); b.Dispose();
g.Dispose(); UpdateUI("绘图完毕!");
SaveImg();
} private void allWork()
{
DrawMap();
} // 切换回UI线程执行的入口
// 现在没问题了,使用Invoke使得线程总是回到UI线程,所以我们可以放心大胆地调用控件的成员了
private void UpdateUI(string str)
{…… }
private void SaveImg()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate();
pictureBox1.Image.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
}
}
这样也没问题
如果修改一下,结果又出错
private void SaveImg()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new dg2(SaveImg));
}
else
{
pictureBox1.Image.Save(AppDomain.CurrentDomain.BaseDirectory + "result\\AR24.gif", System.Drawing.Imaging.ImageFormat.Gif);
pictureBox1.Image = bmpDraw;
pictureBox1.Invalidate();
}
}
现在的问题就是委托这一步的执行顺序导致的问题