none
img.Save - InvalidOperationException

    Question

  • 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?

    Friday, February 18, 2011 10:58 PM

Answers


  • 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
    Friday, February 18, 2011 11:45 PM

All replies


  • 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
    Friday, February 18, 2011 11:45 PM
  • 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
    Saturday, February 19, 2011 10:46 AM
  •  

    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".
    Sunday, February 20, 2011 1:08 AM