InvalidOperationException while saving a bitmap and using graphics.copyFromScreen parallel-y

Viewed 767

I am writing an application to capture the screen using the CopyFromScreen method, and also want to save the image I capture to send over my local network. So, I am trying store the captured screen on one bitmap, and save another bitmap, which is the previously captured screen, on two threads.

However, this is throwing an InvalidOperationException, which says object is currently in use elsewhere. The exception is thrown by System.Drawing.dll.
I have tried locking, and am using separate bitmaps for saving and capturing the screen. How do I stop this from happening? Relevant code:

Bitmap ScreenCapture(Rectangle rctBounds)
{
    Bitmap resultImage = new Bitmap(rctBounds.Width, rctBounds.Height);

    using (Graphics grImage = Graphics.FromImage(resultImage))
    {
        try
        {
            grImage.CopyFromScreen(rctBounds.Location, Point.Empty, rctBounds.Size);
        }
        catch (System.InvalidOperationException)
        {
            return null;
        }
    }
    return resultImage;
}

void ImageEncode(Bitmap bmpSharedImage)
{
    // other encoding tasks
    pictureBox1.Image = bmpSharedImage;
    try
    {
        Bitmap temp = (Bitmap)bmpSharedImage.Clone();
        temp.Save("peace.jpeg");
    }
    catch (System.InvalidOperationException)
    {
        return;
    }
}

private void button1_Click(object sender, EventArgs e)
{
    timer1.Interval = 30;
    timer1.Start();
}

Bitmap newImage = null;

private async void timer1_Tick(object sender, EventArgs e)
{
    //take new screenshot while encoding the old screenshot 

    Task tskCaptureTask = Task.Run(() =>
        {
            newImage = ScreenCapture(_rctDisplayBounds);
        });
    Task tskEncodeTask = Task.Run(() =>
            {
                try
                {
                    ImageEncode((Bitmap)_bmpThreadSharedImage.Clone());
                }
                catch (InvalidOperationException err)
                {
                    System.Diagnostics.Debug.Write(err.Source);
                }
            });

    await Task.WhenAll(tskCaptureTask, tskEncodeTask);

    _bmpThreadSharedImage = newImage;
}

img1img2

2 Answers
Related