使用另一个IDisposable实现IDisposable的对象

时间:2017-10-18 05:46:26

标签: c# .net idisposable

我尝试在C#中开发一个应用程序,并对MailMessage对象有一些顾虑:

它实现了IDisposable接口,所以我在using语句中使用它。因此它隐含地调用了Dispose方法。现在,使用该对象我需要添加附件,我已将其转换为byte[]对象并将其添加为流。以下是获得更好视图的代码部分:

using(MailMessage message = new MailMessage("john.smith@gmail.com"){
    MemoryStream stream;
    //here I pass byte array to the stream and create an attachemnt
    message.Attachments.Add(new Attachment(stream, "name.xyz"));

    using(SmtpClient client = new SmtpClient("server.com", port))
    {
        // send message
    }
}

现在,我有一个非托管资源:Stream对象。我无法在设置附件后立即关闭它(因此无法调用Dispose方法),因为我在发送邮件时会收到错误,因为它在发送时使用了流。

所以,我需要稍后摆脱它,我发送后会这样做。这是第二个using中的代码:

try
{
    client.Send(messgae);
}
finally
{
    if(stream != null)
        stream.Dispose();
}

现在问题:Dispose MailMesssage方法释放了该对象使用的所有资源。我的Stream对象是其中一个资源,不是吗?因此,当using(MailMessage...终止时,它应该还管理我的Stream对象,不应该吗?所以我不需要手动处理我的Stream对象。

编辑:

建议的方法:

using(MailMessage message = new MailMessage("john.smith@gmail.com"){
    using(MemoryStream stream = ...)
    {
        //here I pass byte array to the stream and create an attachemnt
        message.Attachments.Add(new Attachment(stream, "name.xyz"));

        using(SmtpClient client = new SmtpClient("server.com", port))
        {
            // send message
        }
    }
}

但问题仍然存在:MailMessage使用此Stream - 那么,我们是否还需要自己管理Stream

3 个答案:

答案 0 :(得分:3)

为什么不在发送邮件后丢弃流?

using(MailMessage message = new MailMessage("john.smith@gmail.com"))
{
    using(var stream = new MemoryStream())
    {
        //here I pass byte array to the stream and create an attachemnt
        message.Attachments.Add(new Attachment(stream, "name.xyz"));

        using(SmtpClient client = new SmtpClient("server.com", port))
        {
        // send message
        }
    }
}

答案 1 :(得分:2)

试试这个:

using(MailMessage message = new MailMessage("john.smith@gmail.com")
using(MemoryStream stream = new MemoryStream())
using(SmtpClient client = new SmtpClient("server.com", port))
{
    message.Attachments.Add(new Attachment(stream, "name.xyz"))
    client.Send(messgae);
}

如果您将MemoryStream放在using块中,它将与您的try/finally块做同样的事情。

答案 2 :(得分:2)

使用using时,您不需要参考文档。

Mail Message处置Attachment Collection,然后处置其所有附件。

关于,如果我们采取或依赖这种方法,那么我完全赞同Zohar

  

IDisposable的处理应在您的代码中表达,方法是通过显式调用Dispose或使用using语句。