I'm trying to make a multithreaded program that takes a certain bitmap from a picturebox where each thread analyzes and changes part of it and then saves it back to the picturebox. I've used a lock() for the instructions that deal with the shared bitmap object and the picturebox but for some reason i still get "Object is currently in use elsewhere" errors every 6-10 runs.
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();
}
I've tried to read as much as I could find on the lock() method but it's still a bit unclear so I might have misused it. So my question is, why isn't the lock preventing threads from executing the instructions? Have I misused it? Or is there a workaround I could use?
Any help with this is greatly appreciated.
The reason why is that the variable pictureBox1
has an affinity to the GUI thread. You cannot access it and change it's value from a separate background thread. In order to change the value you must do it from the thread the variable is associated with. This is typically done via .Invoke
Try this instead
pictureBox1.Invoke((MethodInvoker)(() => pictureBox1.Image = bmp2));
Even then I think you still have issues because the value bmp2 is used from multiple threads. The variable pictureBox1
will attempt to render this value on the GUI thread while the background thread is creating a graphics object on top of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With