Неверный параметр - PullRequest
0 голосов
/ 26 мая 2018

У меня есть конкретная проблема, и я не знаю, как ее решить.Я сделал программу в winforms, которая заняла все время снимки экрана в Task.Его работа около нескольких минут и вылетает.

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

Это ошибка Visual Studio:

This is error from MessageBox

The parameter is invalid

System.ArgumentException HResult = 0x80070057 Сообщение = Параметр недействителен.Source = System.Drawing Stack trace: в System.Drawing.Bitmap..ctor (ширина Int32, высота Int32, формат PixelFormat) в System.Drawing.Bitmap..ctor (ширина Int32, высота Int32) в TibiaHelper.Form1.CopyScreen (в) в C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs: строка 157 в TibiaHelper.Form1.Проверьте уровеньHP () в C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \Form1.cs: строка 368 в TibiaHelper.Form1.b__22_0 () в C: \ Users \ Pawel \ source \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs: строка 308 в System.Threading.Tasks.Task.InnerInvoke () в системе.Threading.Tasks.Task.Execute ()

1 Ответ

0 голосов
/ 26 мая 2018

Вам не хватает памяти и / или смежного адресного пространства.Последнее вполне вероятно, если вы находитесь в 32-битном процессе.Должна помочь правильная утилизация графики и растрового изображения, когда вы закончите.Также рассмотрите возможность повторного использования того же растрового изображения, если размер экрана не изменился.Растровое изображение размером с экран довольно большое.

Следующий код завершит работу с этим исключением после 30 итераций.

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

Это будет выполнено просто отлично, но это займет некоторое время и будет довольно расточительным.

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

Обновление: Из ваших правок я вижу, что вы не избавляетесь от графического объекта.Вы также должны определенно повторно использовать растровое изображение и графику, как это

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