rootpanthera
rootpanthera

Reputation: 2771

Delete image file right after compressing is complete. How?

I have a website which allow a user to upload some image on the server via upload form. When this image is uploaded, asp.net service should compress that particular image. Compressing an image already works great but I would like to delete an original image from server's disk when compressing is complete.

Please take a moment and look at my code below:

 if (fileUl.PostedFile.ContentType == "image/jpeg" || fileUl.PostedFile.ContentType == "image/png") 
 {
    fileUl.SaveAs(fullPath);
    System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath); 
    compressImage(destinationPath, image, 40);
     System.IO.File.Delete(fullPath);

 } // nested if

If I try to run code above I'm getting

System.IO.IOException: The process cannot access the file [filepath] because it is being used by another process.

I actually expect that because I think it's because, server is still compressing an image when next line of code wants to delete that image (I think this is it). So my question is:

How to wait for compressing to be complete and then run "delete" code?

Upvotes: 1

Views: 557

Answers (5)

Irfan
Irfan

Reputation: 2771

using (System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
{
  //DO compression;
}
System.IO.File.Delete(fullPath);

Better do it all in compress function:

public void DoCompression(string destination, string fullPath, int ratio)
{
    using (System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
    {
      //DO compression by defined compression ratio.
    }
}

The caller function may look like:

DoCompression(destinationPath, fullPath, 40);
DoCompression(destinationPath, fullPath, ??);

System.IO.File.Delete(fullPath);

Upvotes: 2

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239784

From Image.FromFile:

The file remains locked until the Image is disposed.

Try:

System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath); 
compressImage(destinationPath, image, 40);
image.Dispose(); //Release file lock
System.IO.File.Delete(fullPath);

or (slightly cleaner if an exception is thrown):

using(System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
{
    compressImage(destinationPath, image, 40);
}
System.IO.File.Delete(fullPath);

Upvotes: 2

Kjetil Watnedal
Kjetil Watnedal

Reputation: 6167

Wrap the image in a Using statmement to ensure proper disposal of the image object.

if (fileUl.PostedFile.ContentType == "image/jpeg" || fileUl.PostedFile.ContentType == "image/png") 
{
    fileUl.SaveAs(fullPath);
    using(System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
    {
        compressImage(destinationPath, image, 40); 
    }
    System.IO.File.Delete(fullPath);
} // nested if

Upvotes: 0

oleksii
oleksii

Reputation: 35925

Several approaches

  • Use sequential execution

    • Blocking compress image
    • Blocking delete image

    As others suggested make sure you free the resources correctly after each stage

  • Use wait handles, such as ManualResetEvent

  • Implement a queueing producer-consumer, where producer enqueues an image to be processed, and consumer dequeues an item, compresses it and deletes original image. Producer and consumer are likely to be different processes.

I would probably go for the first approach as it is simple. Second approach is easy to implement, but it holds threads and degrades performance of web application. The third approach is useful if your web site is under heavy load.

Upvotes: 0

Mahmood Dehghan
Mahmood Dehghan

Reputation: 8265

It depends on what you are doing in compressImage. if you are using threads to compress the image then you are right. but I think different. You have to Dispose the image object.

Upvotes: 0

Related Questions