Invalid Parameter

-1

I have specific problem and i dont know how to solve it. I has been made program in winforms which taking all time screenshoots in Task. Its work about few minutes and crashes.

           private void TaskBot()
        {
            Task taskHeal = new Task(() =>
            {

                while (boolCheckBoxHP != null)
                {
                    Thread.Sleep(200);
                    if (boolCheckBoxHP == true)
                    {
                        Bitmap bitmap;

                        try
                        {
                            bitmap = new 
//THERE IS AN ERROR
Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
//THERE IS AN ERROR
                            Graphics graphics = Graphics.FromImage(bitmap);
                            graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error: " + ex.Message + "\n\nCause: " + "SpriteSet not yet loaded.");
                            bitmap = null;
                        }

                        KontrolujPoziomHP(bitmap);
                        if (bitmap != null) bitmap.Dispose();
                    }

                    if (boolCheckBoxMana == true)
                    {
                        Bitmap bitmap;

                        try
                        {
                            bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
                            Graphics graphics = Graphics.FromImage(bitmap);
                            graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);

                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error: " + ex.Message + "\n\nCause: " + "SpriteSet not yet loaded.");
                            bitmap = null;
                        }
                        Thread.Sleep(50);
                        KontrolujPoziomMany(bitmap);
                        if (bitmap != null) bitmap.Dispose();
                    }
                }
            });
            taskHeal.Start();
        }

This is an error from Visual Studio:

This is error from MessageBox

The parameter is invalid

System.ArgumentException HResult = 0x80070057 Message = Parameter is invalid. Source = System.Drawing Stack trace: in System.Drawing.Bitmap..ctor (Int32 width, Int32 height, PixelFormat format) in System.Drawing.Bitmap..ctor (Int32 width, Int32 height) in TibiaHelper.Form1.CopyScreen (in ) in C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs: line 157 in TibiaHelper.Form1.Check the LevelHP () in C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs : line 368 in TibiaHelper.Form1.b__22_0 () in C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs: line 308 in System.Threading.Tasks.Task.InnerInvoke () in System.Threading. Tasks.Task.Execute ()

c#
winforms
bitmap
task
system.drawing
asked on Stack Overflow May 25, 2018 by PaweÅ‚ Traczyk • edited May 25, 2018 by PaweÅ‚ Traczyk

1 Answer

1

You're running out of memory and/or contiguous address space. The latter is quite likely if you're in a 32-bit process. Properly disposing of both the graphics and the bitmap when you're done with should help. Also consider reusing the same bitmap if the size of the screen hasn't changed. A screen-sized bitmap is pretty big.

The following code will crash with that exception after 30 something iterations.

for (int i = 0; i < 500; i++)
{
    new Bitmap(5000, 5000);
}

This will complete just fine, but it will take a while and is quite wasteful.

for (int i = 0; i < 500; i++)
{
    new Bitmap(5000, 5000).Dispose();
}

Update: From your edit I can see you're not disposing of the graphics object. You also should definetly reuse the bitmap and graphics like this

private async Task Foo(CancellationToken cancel)
{
    using (var bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
    using (var graphics = Graphics.FromImage(bitmap))
    {
        while (true)
        {
            cancel.ThrowIfCancellationRequested();
            graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
            ProcessImage(bitmap);
            await Task.Delay(200);
        }
    }
}
answered on Stack Overflow May 25, 2018 by Billy • edited May 25, 2018 by Billy

User contributions licensed under CC BY-SA 3.0