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);
}
}
}