【问题标题】:When to use Dispose or when to use Using何时使用 Dispose 或何时使用 Using
【发布时间】:2014-03-28 01:51:30
【问题描述】:

我最近遇到了必须在 C# 程序中硬编码 Dispose 方法的情况。否则,电子邮件中使用的文件将被“永远”锁定,甚至 Process Manager 都无法告诉我是谁/什么锁定了它。我不得不使用 Unlocker Assistant 来强制删除文件,但我担心现在我在服务器上留下了一些分配的内存块。

我指的代码是这样的:

MailMessage mail = new MailMessage();
mail.From = new MailAddress("reception@domain.com", "###");
mail.Subject = "Workplace Feedback Form";
Attachment file = new Attachment(uniqueFileName);
mail.Attachments.Add(file);
mail.IsBodyHtml = true;
mail.CC.Add("somebody@domain.com");
mail.Body = "Please open the attached Workplace Feedback form....";

//send it
SendMail(mail, fldEmail.ToString());

上面的代码让来自uniqueFileName的文件被附件句柄锁定,我无法删除它,因为这段代码是从客户端机器(而不是服务器本身)运行的,文件句柄是不可能的去寻找。

在我强制删除文件后,我从另一个论坛发现我应该处理掉附件对象。

所以我在发送电子邮件后添加了这些代码行...

//dispose of the attachment handle to the file for emailing, 
//otherwise it won't allow the next line to work.
file.Dispose(); 

mail.Dispose(); //dispose of the email object itself, but not necessary really
File.Delete(uniqueFileName);  //delete the file 

我是否应该将其封装在 using 语句中?

这就是我的问题的症结所在。我们什么时候应该使用 Using,什么时候应该使用 Dispose?我希望两者之间有一个明显的区别,如果你做“X”然后使用这个,否则使用那个。

这个When to Dispose? 和这个C# Dispose : when dispose and who dispose it 确实在一定程度上回答了我的问题,但我仍然对何时使用它们的“条件”感到困惑。

【问题讨论】:

  • 值得注意的是,我在 Microsoft 框架中专门为 ftp 遇到了一些类,这些类没有在转换为另一种对象类型时可以继承的 dispose 方法。当我从 FtpWebRequest 转换 FtpWebResponse 时遇到了其中之一,因为原始对象不继承 IDisposable 我传输的文件被锁定。因此,即使知道您将它们设置在 using 语句中,它也对您没有任何好处。无论我做什么,您都可能需要手动关闭它们。我有一个 try catch 语句,如果你想要的话,我可以简单地检查文件锁定消息。
  • 当我遇到它时,我只需要穿过那座桥,但你是对的,我会记住这一点。谢谢

标签: c# asp.net dispose using handles


【解决方案1】:

using 在 C# 中:

using(MyDisposableType obj = new MyDisposableType())
{
  ...
}

是“语法糖”(或简写符号),相当于

MyDisposableType obj = new MyDisposableType();
try {
  ...
} finally {
  obj.Dispose();
}

http://msdn.microsoft.com/en-us//library/yh598w02.aspx中所述

【讨论】:

  • 简单的答案。但是@dstanley 接受了它,因为他的回答实际上回答了需要的情况。谢谢
【解决方案2】:

我应该将其包装在 using 语句中吗?

或者将主代码放在try 块中,将Dispose 放在finally 块中。

using 只是用更少的代码安全地实现了Dispose 模式。 using 将把Dispose 放在finally 块中,这样即使抛出异常,对象也会被释放。你现在的方式,如果抛出异常,对象将不会被释放,而是在垃圾收集时被清理。

我从未遇到过我不能使用using必须手动使用try/finallyDispose()的情况。

所以选择权在你手中 - 你可以在 finally 块中使用 Dispose,它可能与使用 using 相同。

【讨论】:

  • +1。不能使用using 的一种情况是对文件的长时间运行操作。 IE。如果您在程序执行期间将事件记录到文件中,您最终会在多个方法的生命周期内长时间保持文件打开。
  • @AlexeiLevenkov 所以你保留对一次性对象的引用并继续处理/重新打开它?
  • 不,我的意思是你只是长时间保持文件打开而不处理/关闭。当您决定切换到新的日志文件/停止记录时,您处置(关闭)该文件。或者不仅仅是记录 - 一些文本编辑器可能会保持文件打开,直到用户关闭文件 - 再次使创建和处置超出单一方法的范围。
  • 谢谢@DStanley。这就是答案。
猜你喜欢
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-24
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
相关资源
最近更新 更多