2017-07-27 97 views
2

我有一个Visual Studio C#应用程序,它的任务是下载图片,进行一些操作,如旋转和翻转和Finnaly将新图片存储在外部HD中。在执行过程中没有内存的应用程序

我有几个线程正在做同样的工作。

当应用程序运行了几个小时后,就会出现一个异常,表明缺少存储空间。

下图显示了应用程序启动时的进程内存,但当它运行一段时间后,此类内存增加到3Gb。

enter image description here

在我关闭所有流,memorystreams,位图,实例等程序。 因此,问题是,如何在执行过程中释放内存或避免内存增加?

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 [email protected]", 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; 
    } 
}    
+1

你需要显示代码在哪里通过内存咀嚼 –

+0

我有应用程序正在运行。一旦出现异常,我会拍照。 – Apalabrados

+0

你也处置这些对象吗? –

回答

2

我建议你换行实现在usingIDisposable所有对象。我会证明你的代码的响应部分:

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; 

    (WebResponse response = request.GetResponse()) 
    { 
      // Rest of your code inside here 
    } 
} 

这是你所使用的图像资源尤为重要。

BitmapFrame image200 = null; 
BitmapFrame image100 = null; 

using(Bitmap image_rotated = CropImage(RotateFlipImage(BitmapImage2Bitmap(image)))) 
{ 
    if (image_rotated == null) 
    { 
      _parent.working_image = "Error procesado imagen"; 
      _parent.isWorking = false; 
      return false; 
    } 

    image200 = CreateResizedImage(Bitmap2BitmapImage(image_rotated), "large"); 
    image100 = CreateResizedImage(Bitmap2BitmapImage(image_rotated), "short"); 
} 

您也应该检查方法Bitmap2BitmapImage

+0

欧普似乎正在妥善处置一次性用品,虽然 –

+0

@EmrahSüngü我没有看到任何处置'image_rotated'例如 –

+0

啊是的'位图'不处理! –

1

你是不是你的处置位图,BitmapFrames或图像的。我不确定你在创建图像的位置,但是我建议在本地创建它 - 所以在完成处理后可以在本地处理它。

在Using语句中包装位图和图像的本地创建,它将在执行后立即处理对象。这个问题有更多的细节该

Right way to dispose Image/Bitmap and PictureBox

你也可以在你的图像对象调用Dispose()。尝试在本地创建映像,并在完成后将其丢弃。使用Finalize()方法来清理BitmapFrame的资源。

您也可以在您的图像对象上调用Dispose。尝试在本地创建映像,并在完成后将其丢弃。

+0

我想我们不应该自己调用Finalize()方法吗?我不知道 –

+0

@EmrahSüngü我认为创建局部变量并将它们包装在使用块中会更好 –

相关问题