InvalidOperationException - object is currently in use elsewhere - red cross
c#, gdi+, invalidoperationexception, multithreading, winforms
Solution
This is because Gdi+ Image class is not thread safe. Hovewer you can avoid InvalidOperationException by using lock every time when you need to Image access, for example for painting or getting image size:
Image DummyImage;
// Paint
lock (DummyImage)
e.Graphics.DrawImage(DummyImage, 10, 10);
// Access Image properties
Size ImageSize;
lock (DummyImage)
ImageSize = DummyImage.Size;
BTW, invocation is not needed, if you will use the above pattern.
Problem
I have a C# desktop application in which one thread that I create continously gets an image from a source(it's a digital camera actually) and puts it on a panel(panel.Image = img) in the GUI(which must be another thread as it is the code-behind of a control. The application works but on some machines I get the following error at random time intervals(unpredictable) ``` ************** Exception Text ************** System.InvalidOperationException: The object is currently in use elsewhere. ``` Then the panel turns into a red cross, red X - i think this is the invalid picture icon that is editable from the properties. The application keeps working but the panel is never updated. From what I can tell this error comes from the control's onpaint event where I draw something else on the picture. I tried using a lock there but no luck :( The way I call the function that puts the image on the panel is as follows: ``` if (this.ReceivedFrame != null) { Delegate[] clients = this.ReceivedFrame.GetInvocationList(); foreach (Delegate del in clients) { try { del.DynamicInvoke(new object[] { this, new StreamEventArgs(frame)} ); } catch { } } } ``` this is the delegate: ``` public delegate void ReceivedFrameEventHandler(object sender, StreamEventArgs e); public event ReceivedFrameEventHandler ReceivedFrame; ``` and this is how the function inside the control code-behind registers to it: ``` Camera.ReceivedFrame += new Camera.ReceivedFrameEventHandler(camera_ReceivedFrame); ``` I also tried ``` del.Method.Invoke(del.Target, new object[] { this, new StreamEventArgs(b) }); ``` instead of ``` del.DynamicInvoke(new object[] { this, new StreamEventArgs(frame) }); ``` but no luck Does anyone know how I could fix this error or at least catch the error somehow and make the thread put the images on the panel once again?