0

I have a background thread generating a Bitmap, when it has a frame ready it call the event OnRenderScreen which contains a byte[] with the generate image I copy the data on _frame and Invalidate a picture box that paints the actual bitmap inside it's client area, it works just fine but if I maximize the form I get a System.InvalidOperationException: 'Object is currently in use elsewhere.'. I suspect it's a problem trying to make changes to the UI thread from the background thread but not sure what would be the correct way to do it.

My current code :

    class Ui : Form
{
    Bitmap _frame;
    Thread _nesThread;

    private PictureBox pbRenderOutput;

    public Ui()
    {
        this._console = new Console();
        _console.OnRenderScreen += _console_OnRenderScreen;

        _frame = new Bitmap(256, 192, PixelFormat.Format32bppArgb);

    }

    private void _console_OnRenderScreen(object sender, RenderEventArgs e)
    {
        RenderScreen(e.FrameData);
    }

    private void RenderScreen(byte[] frameData)
    {
        BitmapData bmpData = _frame.LockBits(new Rectangle(0, 0, _frame.Width, _frame.Height), ImageLockMode.WriteOnly, _frame.PixelFormat);

        byte[] pixelData = new byte[bmpData.Stride * bmpData.Height];
        Buffer.BlockCopy(frameData, 0, pixelData, 0, pixelData.Length);

        Marshal.Copy(pixelData, 0, bmpData.Scan0, pixelData.Length);

        _frame.UnlockBits(bmpData);

        pbRenderOutput.Invalidate();
    }


    private void pbRenderOutput_Paint(object sender, PaintEventArgs e)
    {
        if (_frame != null)
        {
            e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            e.Graphics.DrawImage(_frame, ClientRectangle, new Rectangle(0, 0, _frame.Width, _frame.Height), GraphicsUnit.Pixel);
        }
    }
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Marc
  • 2,023
  • 4
  • 16
  • 30
  • `RenderScreen` indirectly calls `Paint` via the `Invalidate`. resizing the window will too, but then `_frame` might still be locked. what throws the exception? the `DrawImage` call in `Paint`? – Cee McSharpface Jun 17 '20 at 13:23
  • This line throws the exception:BitmapData bmpData = _frame.LockBits(new Rectangle(0, 0, _frame.Width, _frame.Height), ImageLockMode.WriteOnly, _frame.PixelFormat); – Marc Jun 17 '20 at 14:07
  • [some thoughts](https://stackoverflow.com/q/55044684/1132334), and [here](https://stackoverflow.com/a/4883902/1132334) – Cee McSharpface Jun 17 '20 at 14:10

0 Answers0