Se eseguo il codice qui sotto, OutOfMemoryException
avviene sia presso la linea diC# Bitmap - Non riesco a trovare come rimuovere OutOfMemoryException
using (Bitmap bitmap1 = new Bitmap(FrameToFilePath(interval.Start - 1)))
o la linea
using (Bitmap bitmap2 = new Bitmap(FrameToFilePath(interval.End + 1)))
Quando viene eseguito il interno per dichiarazione circa 1000 volte.
Tuttavia, non so perché si verifichi OutOfMemoryException. Penso di aver scritto abbastanza using
per disporre gli oggetti Bitmap
. Dove si verifica la perdita di memoria?
class Program
{
static void Main(string[] args)
{
// Some code to initialize List<Interval> intervals
Parallel.ForEach(intervals, interval =>
{
using (Bitmap bitmap1 = new Bitmap(FrameToFilePath(interval.Start - 1)))
using (Bitmap bitmap2 = new Bitmap(FrameToFilePath(interval.End + 1)))
{
for (int i = interval.Start; i <= interval.End; i++)
{
ColorMatrix colorMatrix = new ColorMatrix(); // Identity matrix
colorMatrix.Matrix33 = (i - interval.Start + 1F)/(interval.Span + 1F); // Alpha
using (ImageAttributes imageAttributes = new ImageAttributes())
using (Bitmap intermediate = new Bitmap(bitmap1.Width, bitmap1.Height, PixelFormat.Format32bppArgb))
using (Graphics graphics = Graphics.FromImage(intermediate))
{
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
graphics.DrawImage(bitmap1, 0, 0);
graphics.DrawImage(bitmap2, new Rectangle(0, 0, intermediate.Width, intermediate.Height), 0, 0, bitmap2.Width, bitmap2.Height, GraphicsUnit.Pixel, imageAttributes);
intermediate.Save(FrameToFilePath(i), ImageFormat.Png);
}
}
}
});
}
static string FrameToFilePath(int frame)
{
return string.Format(@"C:\(some path)\frames\frame-{0:00000}.png", frame);
}
}
class Interval
{
public int Start { get; set; }
public int End { get; set; }
public int Span { get { return End - Start + 1; } }
}
EDIT: OK. Forse perché Parallel.ForEach
spawnà le attività prima che le altre attività siano terminate, in modo che vengano avviate sempre più attività, ma i numeri Bitmap
non erano GC in quanto le attività non erano state terminate. Bene, se questo è il caso, come risolverlo per evitare OutofMemoryException? Non sono sicuro che sia ancora così ...
Forse un MemoryFailPoint può essere di aiuto (http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint%28v=vs.110%29.aspx) –
Esattamente lo stesso problema di [questa domanda] (http://stackoverflow.com/questions/25907829/why-is-parallel-foreach-much-faster-then-asparallel-forall-even-though-msdn). –