Ошибка System.Runtime.InteropServices.ExternalException: "A generic error occurred in GDI+." после того, как добавил 1 метод в программу

В моей программе достаточно много раз нужно сохранять скриншоты и затем обрабатывать их. Раньше ошибок не появлялось и работало исправно часами. Но теперь, когда я добавил следующий метод:

 private async Task CheckTable()
 {
     Image image = CaptureScreen(757, 476, 0, 0, size3);

     image.Save(@"C:\ImageTests\screeeen.jpg", ImageFormat.Jpeg);


     using (Tesseract tesseract = new Tesseract(@"C:\langs", "rus", OcrEngineMode.TesseractLstmCombined))
     {
         tesseract.SetImage(new Image<Bgr, byte>(@"C:\ImageTests\screeeen.jpg"));
         tesseract.Recognize();
         if (tesseract.GetUTF8Text().Replace("\r\n", "").Contains("Вы успешно") || tesseract.GetUTF8Text().Replace("\r\n", "").Contains("не доступен"))
         {
             return;
         }
         else
         {
            await Task.Delay(50);
            await  CheckTable();
         }
     }
 }

и использовал в коде его так:

var tableCheck = CheckTable();
await tableCheck;
tableCheck.Dispose();

то в случайном фрагменте кода, где я тоже выполнял сохранение фотографий, начала спустя некоторое количество времени вылезать ошибка:

System.Runtime.InteropServices.ExternalException: "A generic error occurred in GDI+."

Как это можно исправить?


Ответы (1 шт):

Автор решения: aepot

Картинку задиспозить забыли, поэтому она файл не отпустила

using (Image image = CaptureScreen(757, 476, 0, 0, size3))
{
    image.Save(@"C:\ImageTests\screeeen.jpg", ImageFormat.Jpeg);
}

Вообще у GDI+ есть странности при работе с файлами, но их стоит учитывать.

Что касается tableCheck.Dispose(); - то Task.Dispose() вызывать не нужно.

await CheckTable();

Избавиться от рекурсии можно так, вам кстати и асинхронность в методе не нужна

private bool CheckTable()
{
    using (Image image = CaptureScreen(757, 476, 0, 0, size3))
    {
        image.Save(@"C:\ImageTests\screeeen.jpg", ImageFormat.Jpeg);
    }

    using (Tesseract tesseract = new Tesseract(@"C:\langs", "rus", OcrEngineMode.TesseractLstmCombined))
    {
        tesseract.SetImage(new Image<Bgr, byte>(@"C:\ImageTests\screeeen.jpg"));
        tesseract.Recognize();
        bool result = tesseract.GetUTF8Text().Replace("\r\n", "").Contains("Вы успешно") || tesseract.GetUTF8Text().Replace("\r\n", "").Contains("не доступен");
        return result;
    }
}

А вызывать вот так

while (!CheckTable())
{
    await Task.Delay(50);
}

Кстати, можно вообще без файла обойтись

private bool CheckTable()
{
    using Tesseract tesseract = new Tesseract(@"C:\langs", "rus", OcrEngineMode.TesseractLstmCombined);
    Image<Bgr, byte> image = CaptureScreen(757, 476, 0, 0, size3).ToImage();
    tesseract.SetImage(image);
    tesseract.Recognize();
    string text = tesseract.GetUTF8Text().Replace("\r\n", ""); 
    bool result = text.Contains("Вы успешно") || text.Contains("не доступен");
    return result;
}
→ Ссылка