C#Threading Bitmap对象/ PictureBox

我有一些代码可以显示移动点的video图形。

我正在将点写入位图,并将其放在图片框上。

图形计算必须在自己的线程上完成。 只要你不“太多”移动窗口,图形就可以正常工作。

我正在使用winforms。 当我运行代码,然后疯狂地移动窗口时,我有时会遇到以下错误:

@ this.Invoke(d,new object [] {bmp}); “无法访问已处置的对象。对象名称:’Form1’。”

@gfx.DrawImage(bmpDestination,new Point()); “对象目前正在其他地方使用。”

这是代码:

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

跨线程使用GDI对象存在问题。

看看汉斯在这个post中的双重克隆建议。

无法访问已处置的对象。 对象名称:’Form1

你得到这个是因为当用户关闭表单时你没有做任何事情来阻止线程。 你必须保持表单活着,直到你知道线程已经死了。 很难做到可靠,请查看此答案以获得解决方案。

另外,调用InvokeRequired是一种反模式。 您知道您正在从工作线程进行调用。 如果InvokeRequired会返回false,那么就会出现问题。 不要打扰,直接调用Invoke()。

对象目前在其他地方使用

当GDI +(Graphics)看到两个线程同时尝试访问位图时,它是一个例外。 在你的代码片段中并不明显,但我看不出GraphingUtility.create()的作用。 确保它创建一个新的位图,而不是返回现有的位图。 因为当你的线程再次写入它并且图片框同时重新绘制时它会爆炸。 你在它上面使用的bmp构造函数没有做任何事情。

你的PictureBox.Image赋值忘记处理旧的。