我有一个网站,允许用户通过上传表单在服务器上上传一些图像。上传此图像时,asp.net服务应该压缩该特定图像。压缩图像已经很好用,但我想在压缩完成后从服务器磁盘中删除原始图像。
请花一点时间查看下面的代码:
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
如果我尝试运行上面的代码,我就会
System.IO.IOException:进程无法访问文件[filepath],因为它正由另一个进程使用。
我实际上是因为我认为这是因为,当下一行代码要删除该图像时,服务器仍在压缩图像(我认为就是这样)。所以我的问题是:
如何等待压缩完成然后运行“删除”代码?
答案 0 :(得分:2)
文件保持锁定状态,直到
Image
被处理。
尝试:
System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath);
compressImage(destinationPath, image, 40);
image.Dispose(); //Release file lock
System.IO.File.Delete(fullPath);
或(如果抛出异常,则稍微清洁):
using(System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
{
compressImage(destinationPath, image, 40);
}
System.IO.File.Delete(fullPath);
答案 1 :(得分:2)
using (System.Drawing.Image image = System.Drawing.Image.FromFile(fullPath))
{
//DO compression;
}
System.IO.File.Delete(fullPath);
最好在压缩功能中做到这一切:
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.
}
}
来电者功能可能如下所示:
DoCompression(destinationPath, fullPath, 40);
DoCompression(destinationPath, fullPath, ??);
System.IO.File.Delete(fullPath);
答案 2 :(得分:0)
这取决于您在compressImage
中所做的事情。如果你使用线程压缩图像,那么你是对的。但我认为不同。您必须Dispose
image
个对象。
答案 3 :(得分:0)
几种方法
使用顺序执行
正如其他人建议的那样,确保在每个阶段后正确释放资源
使用等待句柄,例如ManualResetEvent
实现排队生产者 - 消费者,其中生产者将要处理的图像排队,消费者将项目出列,压缩并删除原始图像。生产者和消费者可能是不同的过程。
我可能会选择第一种方法,因为它很简单。第二种方法易于实现,但它保留了线程并降低了Web应用程序的性能。如果您的网站负载很重,第三种方法很有用。
答案 4 :(得分:0)
将图像包裹在Using statmement中以确保正确处理图像对象。
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