Растровое изображение 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);
}
}