Reputation: 2771
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
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
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
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
Reputation: 35925
Several approaches
Use sequential execution
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
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