Search code examples
c#access-violationmemorystream

C# - MemoryStream, image.Save in a loop - random protected memory error


While grabbing images (Image type) to convert them into "Base64 String" in a kind of loop, im always getting this error at a random time of the execution.

"Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

        private void doCapture()
        {
            CaptureInfo.CaptureFrame();
        }

        void CaptureInfo_FrameCaptureComplete(PictureBox Frame)
        {
            string str = toB64img(Frame.Image);
            //do something with the string
            this.doCapture();
        }

        private string toB64img(Image image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, ImageFormat.Png);   <==== error HERE
                byte[] imageBytes = ms.ToArray();
                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                return base64String;
            }
        }

Image come from directx.capture, webcam capture. (working fine) I assume that's because something is still in access and wasn't closed yet, so error cause already in use. But how can i fix this issue please?


Solution

  • i was right in my though. Something wasn't freed fast enought. Adding a force GC check right before the RETURN of the function, worked like a charm.. strange.

    private string toB64img(Image image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Convert Image to byte[]
                image.Save(ms, ImageFormat.Png);   
                byte[] imageBytes = ms.ToArray();
                // Convert byte[] to Base64 String
                string base64String = Convert.ToBase64String(imageBytes);
                GC.Collect();                       <======
                GC.WaitForPendingFinalizers();      <======
                GC.Collect();                       <======
                return base64String;
            }
        }
    

    ``