Утилизировать MemoryStream при использовании с .Net Mail Attachment

Я использую MemoryStream для добавления вложений из двоичного файла, который хранится в БД. Моя проблема в том, что я хочу правильно избавиться от MemoryStream. Это легко сделать с помощью оператора «using», но когда у меня есть более одного вложения, я не знаю, как правильно избавиться от нескольких потоков памяти.

Есть ли хороший способ перебрать и прикрепить файлы, но в то же время правильно избавиться от MemoryStreams, которые я использую для присоединения? Когда я пытался сбросить/закрыть перед использованием smtp.Send через ошибку, указав, что поток уже закрыт.

Мы ценим любые предложения.


person scarpacci    schedule 24.01.2012    source источник
comment
Метод MailMessage.Dispose() уже удаляет свои вложения, вам не нужно помогать.   -  person Hans Passant    schedule 24.01.2012
comment
@HansPassant Это должен быть ответ. Намного лучше, чем держать список потоков, а потом все это выбрасывать.   -  person talles    schedule 14.08.2013
comment
@HansPassant Я только что заметил, что он применяется только с System.Net.Mail.MailMessage, а не с устаревшим System.Web.Mail.MailMessage, который не реализует Idisposeable   -  person Royi Namir    schedule 08.06.2014
comment
Ну, вы выяснили одну причину, по которой это устарело. CDO стар, как камень.   -  person Hans Passant    schedule 08.06.2014


Ответы (3)


Вы можете перебирать MemoryStream и удалять их. Помещение удаляющего кода в блок finally эквивалентно оператору using.

var list = new List<MemoryStream>(){new MemoryStream(), new MemoryStream()};

try
{
    //....
}
finally
{
    foreach (var x in list)
    {
        x.Dispose();
    }
}

Оператор using гарантирует, что Dispose вызывается, даже если во время вызова методов объекта возникает исключение. Вы можете добиться того же результата, поместив объект в блок try, а затем вызвав Dispose в блоке finally; на самом деле именно так оператор using транслируется компилятором.

из MSDN

person gdoron is supporting Monica    schedule 24.01.2012
comment
Спасибо @gdoron, я посмотрю ... ценю пример - person scarpacci; 24.01.2012
comment
Зачем создавать список? Класс Attachment имеет доступ к Stream с помощью свойства ContentStream класса Attachment. Затем вы можете сначала удалить поток, а затем удалить вложение в блоке finally. См. MSDN [ссылка]( msdn.microsoft.com/en-us/library/) Я решил сделать это, потому что не все мои MailMessages имеют вложения, и я не знаю, сколько вложений ожидать, поэтому я не мог использовать оператор using . Я полагаю, что мог бы реструктурировать весь свой код, чтобы приспособить его к использованию, но это казалось проще. - person evodev; 15.02.2015

Я знаю, что это старый пост, но оказывается, что достаточно удалить MailMessage или просто поместить его в оператор using, так как когда MailMessage удаляется, все AttachmentCollection также удаляется, а когда Attachment удаляется, Stream также удаляется. Полный код можно найти в ReferenceSource.

using(MailMessage mail = new MailMessage())
{
   // Add attachments without worring about disposing them
}
person Adil Mammadov    schedule 27.05.2017

person    schedule
comment
Спасибо @leppie ... проблема в том, что у меня может быть от 1 до многих вложений ... я думаю, что список потоков памяти может работать - person scarpacci; 24.01.2012
comment
Возможно, вы можете использовать Container для этого. - person leppie; 24.01.2012
comment
Что вы имеете в виду под container? - person gdoron is supporting Monica; 25.01.2012
comment
@gdoron: На самом деле это не сработает. Я неправильно думал, что класс Container позволяет добавлять любые IDisposable, но, посмотрев, он принимает только IComponent. :( - person leppie; 25.01.2012