Решил я попробовать использовать yield
в своем проекте и столкнулся с проблемой утечки памяти.
Вот пример кода с использованием yield
:
public IEnumerable<ExportImage> ProcessMultipleExportImagesMultipleSrcCrop(IEnumerable<ExportImage> bitmaps)
{
int nok = 1;
foreach (var pos in Settings.ImagesReferences)
{
nok = NOK(nok, pos.Length);
}
nok = NOK(nok, bitmaps.Count());
for (int i = 0; i < nok; i++)
{
yield return ProcessSingleExportImageCropSrc(bitmaps.ElementAt(i % bitmaps.Count()), i);
}
}
А вот без:
public IEnumerable<ExportImage> ProcessMultipleExportImagesMultipleSrcCrop(IEnumerable<ExportImage> bitmaps)
{
int nok = 1;
foreach (var pos in Settings.ImagesReferences)
{
nok = NOK(nok, pos.Length);
}
nok = NOK(nok, bitmaps.Count());
var res = new List<ExportImage>();
for (int i = 0; i < nok; i++)
{
res.Add( ProcessSingleExportImageCropSrc(bitmaps.ElementAt(i % bitmaps.Count()), i));
}
return res;
}
Код обрабатывающий результат:
var tmpres = ImageConcatenator.ProcessMultipleExportImagesMultipleSrcCrop(frames);
var res = new SafeIntPtrArray<ExportImage> { Values = tmpres.ToArray(), Size = tmpres.Count() };
foreach (var item in frames)
{
item.Dispose();
}
await Render(res);
В первом случае я получаю утечку памяти при каждом вызове, во втором нет.
Вся память корректно освобождается без использования GC, так как ExportImage
структура из C библиотеки, так что GC винить в этом наверное не целесообразно.
В чем может быть проблема? Ибо хотелось бы использовать yield
, но если с ним такие трудности возникают, то толка нету. Я понимаю, что это я где-то неверно что-то неправильно делаю, но понять не могу. Так что жду подсказки.
P.S. Могу предположить, что при вызове tmpres.ToArray()
где-то там и происходит утечка, но как от нее избавиться?
На самом деле утечка происходит вот тут: tmpres.Count()
. Скорее всего, у вас утекает результат вызова ProcessSingleExportImageCropSrc
, но могу и ошибаться.
Вызов Count()
приводит к полному выполнению вашего генератора, открывается куча ресурсов - которые вы никогда не закрываете!
Правильнее внешний код писать вот так:
var tmpres = ImageConcatenator.ProcessMultipleExportImagesMultipleSrcCrop(frames).ToArray();
var res = new SafeIntPtrArray<ExportImage> { Values = tmpres, Size = tmpres.Length };
foreach (var item in frames)
{
item.Dispose();
}
await Render(res);
Обратите внимание: материализующий вызов - только один, ToArray()
, второго вызова не делается.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
У меня есть переменная типа float, у которой после запятой много цифрМне хотелось бы ограничить её до одного знака после запятой
При загрузке, даже стандартного WindowsForm, ничего еще не меняя, уже вылезает ошибка, как от нее избавиться? И почему она вылезает, если ничего...
Здравствуйте! Пытаюсь получить идентификаторы более, чем у 50 роликов, используя nextPageTokenНо проблема в том, что каждый раз в переменную ids добавляются...
Есть программа которая сравнивает строки по датеНеобходимо чтобы в textBox отображался процесс работы программы, а именно выводились найденные...