我正在尝试编写一个多线程程序,它从picturebox中获取某个位图,每个线程分析并更改其中的一部分,然后将其保存回picturebox。我为处理共享位图对象和picturebox的指令使用了lock(),但由于某些原因,我每运行6-10次就会收到"Object当前在别处使用“的错误。
private Object locker = new Object();
void doThread(Bitmap bmp2) //simplified - other references not important
{
//some code here
//....
lock (locker)
{
Graphics gr = Graphics.FromImage(bmp2); //this is where i get the errors, they're related to bmp2
gr.DrawImage(bmp, new Rectangle(0, 0, 800, 600));
gr.Dispose();
pictureBox1.Image = bmp2;
}
}
void runThreads()
{
Bitmap bmp2 = new Bitmap(pictureBox1.Image);
Thread thread1 = new Thread(delegate() { doThread(bmp2); });
Thread thread2 = new Thread(delegate() { doThread(bmp2); });
Thread thread3 = new Thread(delegate() { doThread(bmp2); });
Thread thread4 = new Thread(delegate() { doThread(bmp2); });
thread1.Start();
thread2.Start();
thread3.Start();
thread4.Start();
}我已经尽可能多地阅读了lock()方法,但它仍然有点不清楚,所以我可能误用了它。所以我的问题是,为什么锁不能阻止线程执行指令?我是不是误用了?或者,有没有我可以使用的变通方法?
这方面的任何帮助都是非常感谢的。
发布于 2010-01-27 01:45:05
原因是变量pictureBox1与GUI线程具有亲和性。你不能从一个单独的后台线程访问它并改变它的值。为了更改该值,您必须在与该变量关联的线程中进行更改。这通常是通过.Invoke完成的
试试这个吧
pictureBox1.Invoke((MethodInvoker)(() => pictureBox1.Image = bmp2));即使这样,我认为您仍然会遇到问题,因为值bmp2是从多个线程使用的。当后台线程在其上创建图形对象时,变量pictureBox1将尝试在GUI线程上呈现该值。
发布于 2010-01-27 02:30:51
修复JaredPar发现的跨线程问题。
然后将pictureBox1.Image设置为bmp2的副本。
Image bmp2copy = bmp2.Clone();
pictureBox1.Invoke((MethodInvoker)(() => pictureBox1.Image = bmp2copy));希望这对你有用。如果不是这样,你可能会考虑组织一个简单的项目来说明这个问题,这样人们就可以实际运行它,并对代码进行模糊处理。在你的头脑中处理问题可能太难了……
https://stackoverflow.com/questions/2141318
复制相似问题