I have a Visual Studio c# app whose task is download pictures, make some operations like rotations and flip and finnaly store the new picture in an external HD.
I have several threads doing the same work.
When the app has been running for a couple of hours, it arises an exception indicating that the lack of storage memory.
The following picture shows the process memory when the app starts, but when it's been running for a while, such memory increase up to 3Gb.
In the program I close all streams, memorystreams, bitmaps, instances and so on. So, the question is, How can I free memory or avoiding the memory increase during the execution?
try
{
request = (HttpWebRequest)WebRequest.Create(new Uri(this._url, UriKind.Absolute));
request.UserAgent = UserAgent.get_user_agent();
noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
request.CachePolicy = noCachePolicy;
response = request.GetResponse();
responseStream = response.GetResponseStream();
reader = new BinaryReader(responseStream);
memoryStream = new MemoryStream();
byte[] bytebuffer = new byte[BytesToRead];
int bytesRead = reader.Read(bytebuffer, 0, BytesToRead);
while (bytesRead > 0)
{
memoryStream.Write(bytebuffer, 0, bytesRead);
bytesRead = reader.Read(bytebuffer, 0, BytesToRead);
}
image.BeginInit();
memoryStream.Seek(0, SeekOrigin.Begin);
image.StreamSource = memoryStream;
image.EndInit();
if ( image.Width < 100 || image.Height < 50 )
{
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
return false;
}
Bitmap image_rotated = CropImage(RotateFlipImage(BitmapImage2Bitmap(image)));
if (image_rotated == null)
{
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
return false;
}
BitmapFrame image200 = CreateResizedImage(Bitmap2BitmapImage(image_rotated), "large");
BitmapFrame image100 = CreateResizedImage(Bitmap2BitmapImage(image_rotated), "short");
// Directorio
int directory_main = (int)(this._Id / 10000);
// Generamos la imagen de 200px
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
String photolocation = @"D:\hilo_" + hilo + "_200.jpg"; //file name
encoder.Frames.Add(BitmapFrame.Create(image200));
FileStream filestream = null;
try
{
using (filestream = new FileStream(photolocation, FileMode.Create))
{
encoder.Save(filestream);
}
// creamos directorio si no existe
System.IO.Directory.CreateDirectory(@"D:\backoffice\originales\" + directory_main + @"\" + this._Id);
if (!this.saveImage(photolocation, @"D:\backoffice\originales\" + directory_main + @"\" + this._Id + @"\" + _filename + "_200.jpg"))
{
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
image = null;
memoryStream.Close();
filestream.Close();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return false;
}
filestream.Close();
// Generamos la imagen de 100px
encoder = new JpegBitmapEncoder();
photolocation = @"D:\hilo_" + hilo + "_100.jpg"; //file name
encoder.Frames.Add(BitmapFrame.Create(image100));
using (filestream = new FileStream(photolocation, FileMode.Create))
{
encoder.Save(filestream);
}
// creamos directorio si no existe
if (!this.saveImage(photolocation, @"D:\backoffice\originales\" + directory_main + @"\" + this._Id + @"\" + _filename + "_100.jpg"))
{
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
image = null;
memoryStream.Close();
filestream.Close();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return false;
}
filestream.Close();
encoder = null;
image100 = null;
image200 = null;
SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-UC7AQ3V\SQLEXPRESS;Integrated Security=SSPI;User ID=frank;password=jungla");
SqlCommand cmd = new SqlCommand("UPDATE dbo.image_objects_download_log SET locked=0, worked=1, isWorking=1 WHERE object_id=@id", con);
cmd.Parameters.AddWithValue("@id", Id);
con.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
con.Close();
_parent.working_image = "Trabajo finalizado con éxito";
_parent.isWorking = false;
image = null;
memoryStream.Close();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return true;
}
catch (IOException e)
{
Console.WriteLine("---------> " + e.Message);
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
image = null;
memoryStream.Close();
filestream.Close();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return false;
}
catch (UriFormatException e)
{
_parent.working_image = "Error procesado imagen";
_parent.isWorking = false;
image = null;
memoryStream.Close();
filestream.Close();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return false;
}
}