Растровое изображение ArgumentException после возврата в оператор using

Так что в настоящее время я работаю над изменяющим размер изображения, который работает / работал довольно хорошо, но за исключением того, что он дал мне исключение OutOfMemoryException, когда я обрабатывал слишком много изображений одновременно, что приводило к сбою программы.

Поэтому, чтобы исправить это, я обернул методы внутри оператора using, чтобы растровые изображения можно было правильно расположить.

Однако я заметил, что если я возвращаю свой Bitmap внутри оператора using, я получаю это сообщение "ArgumentException is unhandled"

Вот мой метод ImageResize:

 public Bitmap ResizeImage(MemoryStream ms, Size size)
    {
        if (comboBox2.Text == "Pixel")
        {
            using (Bitmap img = new Bitmap(new Bitmap(ms, true), size.Width, size.Height))
            {
                var original = new Bitmap(ms, true);
                Graphics graphic = Graphics.FromImage(img);

                //IRRELEVANT CODE.....

                return img;
            }
        }
        else
        {
            return null;
        }

И вот когда я пытаюсь сохранить свое изображение вне метода ImageResize:

private void button1_Click(object sender, EventArgs e)
    {
    //IRRELEVANT CODE ...
    img = ResizeImage(memory, new Size(getX(), getY()));
    //IRRELEVANT CODE ...
    img.Save(outputFileName, codec, encoderParams); //<-Exception occurs here
    }

Когда я удаляю оператор using, все снова работает отлично, однако мне приходится использовать блоки using для удаления битовой карты и, следовательно, для предотвращения утечки памяти. Также, когда я сохраняю изображение внутри оператора using, оно тоже работает нормально, но это не решение в моем случае.

Что я делаю неправильно? Мне кажется, что растровое изображение не возвращается правильно.

Я ценю любую помощь и заранее благодарю Раванда

2 ответа

Решение

Хорошо, я наконец-то исправил проблему с утечкой памяти, оказалось, что я действительно выпускаю / утилизирую изображения, но это не было сделано достаточно быстро, что вызвало исключение outOufMemoryException, когда вы обрабатывали много очень больших изображений сразу после другого. Я пытался сделать все многопоточным и всегда ждал, пока WorkingSet уменьшится, но безуспешно.

Оказалось, что это было проще, чем я думал, все, что мне нужно было сделать, это поместить это в конец моего метода изменения размера:

GC.Collect();
GC.WaitForPendingFinalizers();
System.Threading.Thread.SpinWait(5000);

И это, кажется, делает магию для изменения размера больших изображений размером 10-20 МБ и разрешением 10000x10000. Может кто-нибудь объяснить, почему SpinWait помогает, но не нормальный сон потока? Всякий раз, когда я пытался усыпить нить, это также казалось спящим, освобождая память.

Вы кладете свое использование в неправильном месте. После окончания использования блока (который включает в себя возвращение из него) объект, управляемый блоком, удаляется. Доступ к удаленному растровому изображению является ошибкой.

Ваше использование должно быть здесь вместо:

private void button1_Click(object sender, EventArgs e)
{
    //IRRELEVANT CODE ...
    using(img = ResizeImage(memory, new Size(getX(), getY())))
    {
        //IRRELEVANT CODE ...
       img.Save(outputFileName, codec, encoderParams);
    }
}
Другие вопросы по тегам