1

我有一个网站,允许用户通过上传表单在服务器上上传一些图像。上传此图像时,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],因为它正被另一个进程使用。

我实际上希望这是因为我认为这是因为,当下一行代码想要删除该图像时,服务器仍在压缩该图像(我认为就是这样)。所以我的问题是:

如何等待压缩完成然后运行“删除”代码?

4

5 回答 5

2

来自Image.FromFile

该文件保持锁定状态,直到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);
于 2013-08-27T07:50:28.963 回答
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);
于 2013-08-27T07:53:58.597 回答
0

这取决于你在做什么compressImage。如果您使用线程来压缩图像,那么您是对的。但我认为不同。你必须对Dispose对象image

于 2013-08-27T07:52:18.810 回答
0

几种方法

  • 使用顺序执行

    • 阻止压缩图像
    • 阻止删除图像

    正如其他人建议的那样,确保在每个阶段之后正确释放资源

  • 使用等待句柄,例如ManualResetEvent

  • 实现排队生产者-消费者,生产者将要处理的图像加入队列,消费者将项目出列,压缩并删除原始图像。生产者和消费者可能是不同的过程。

我可能会选择第一种方法,因为它很简单。第二种方法很容易实现,但它会占用线程并降低 Web 应用程序的性能。如果您的网站负载过重,第三种方法很有用。

于 2013-08-27T07:55:41.530 回答
0

将图像包装在Using 语句中,以确保正确处理图像对象。

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
于 2013-08-27T07:57:22.050 回答