img.Save - InvalidOperationException

Answered img.Save - InvalidOperationException

  • Friday, February 18, 2011 10:58 PM
     
      Has Code

    System InvalidOperationException: Object is currently in use elsewhere

     

            private void Detect(Image img)
            {

                IntPtr hbitmap = IntPtr.Zero;
                System.IO.MemoryStream ms = new System.IO.MemoryStream(); try{
                 img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // This line throws error InvalidOperationException randomly } catch {} return;//skip rest ///

            }

     

    I start Detect(imgFrame) as a new single thread. It randomly throws error at line img.Save().

    After function Detect() runs a few (random) times Error image appears at picturebox1 (created by main thread) WITH or WITHOUT error message at Output window. I mean img.Save() might be executed without any error but error image appears at the end. Application runs as expected except I only see diagonal red cross on white background -what we called error image-

    If I put return; just before img.Save() picturebox will be OK all run time.
    If I remark the line in main thread and prevent image assign to picturebox -in endless loop-, no problem.

    //pictureBox1.Image = imgFrame; //no image no cry

    I don't know what is the relation between picturebox.Image = imgFrame and img.Save(img)... imgFrame and img are different things because of default ByVal at function Detect()... Aren't they?

All Replies

  • Friday, February 18, 2011 11:45 PM
    Moderator
     
     Answered


    I don't know what is the relation between picturebox.Image = imgFrame and img.Save(img)... imgFrame and img are different things because of default ByVal at function Detect()... Aren't they?

    No.  If you're passing this in ByVal, it's passing the reference to the image (in memory) by value, but both references "point" to the same Image instance.

     

    As you can see from your random errors, the problem is trying to use the image reference on a separate thread.  This really isn't very safe.


    I would recommend moving the img.Save call out, and rework your "Detect" method to take a reference to the MemoryStream instead.  This will cause it to be safe, as you won't be using "img' in two threads anymore.

     

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked As Answer by Emin Akbulut Sunday, February 20, 2011 12:45 AM
    •  
  • Saturday, February 19, 2011 10:46 AM
     
     

    I though it was ByRef. With ByRef many variables point same memory area as we know.

    I tried to duplicate the image, that's why I use argument in Detect(Image img) instead of global variable.  

    So what is the correct way to clone my image in memory to prevent any conflict between threads? I tried lock before accessing/assigning img & picturebox but still got the exception.

    • Edited by Emin Akbulut Saturday, February 19, 2011 12:00 PM typo
    •  
  • Sunday, February 20, 2011 1:08 AM
    Moderator
     
     

     

    So what is the correct way to clone my image in memory to prevent any conflict between threads? I tried lock before accessing/assigning img & picturebox but still got the exception.

    You can use Image.Clone to make a copy: http://msdn.microsoft.com/en-us/library/system.drawing.image.clone.aspx

     

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".