2011-12-13 9 views
1

Итак, я использовал System.Net.Mail.MailMessage объекты для отправки электронной почты через SmtpClient какое-то время. Я заметил, что MailMessage реализует IDisposable, поэтому я всегда использую его в блоке using.Почему System.Net.Mail.MailMessage реализует IDisposable

using(MailMessage msg = new MailMessage()) 
{ 
    msg.To = blah... etc; 
    ... 
    smtpclient.Send(msg); 
} 

Из метаданных, вы можете увидеть эту информацию об осуществлении MailMessage

// Summary: 
//  Releases all resources used by the System.Net.Mail.MailMessage. 
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] 
public void Dispose(); 
// 
// Summary: 
//  Releases the unmanaged resources used by the System.Net.Mail.MailMessage 
//  and optionally releases the managed resources. 
// 
// Parameters: 
// disposing: 
//  true to release both managed and unmanaged resources; false to release only 
//  unmanaged resources. 
protected virtual void Dispose(bool disposing); 

Но я задаюсь вопросом, почему MailMessage реализовать IDisposable? Кажется, что он не имеет ничего общего с сетевыми элементами, потому что SmtpClient обрабатывает все это.

Возможно ли это из-за потенциального хранения файлов для прикрепленных файлов? Есть ли что-то еще, что я забываю?

+2

Вложения должны быть закрыты для одного. –

ответ

14

Согласно dotPeek, он избавляется от своих привязанностей и его просмотров:

protected virtual void Dispose(bool disposing) 
{ 
    if (!disposing || this.disposed) 
    return; 
    this.disposed = true; 
    if (this.views != null) 
    this.views.Dispose(); 
    if (this.attachments != null) 
    this.attachments.Dispose(); 
    if (this.bodyView == null) 
    return; 
    this.bodyView.Dispose(); 
} 
7

Он реализует IDisposable, потому что у него есть дети, которые реализуют IDisposable. Например, приложение является одноразовым объектом, потому что вложение может быть потоком, который в большинстве случаев нуждается в утилизации. Таким образом, после того, как сообщение было отправлено, для удаления вложения (который содержит поток) требуется удаление сообщения.

4

Если вы поставляете изображения или вложения, то их необходимо очистить при утилизации. Таким образом, вызывать запрет либо неявно в использовании, либо в явном виде - это то, что вы должны делать.

В общем, всегда вызывайте вызов на любом объекте, который реализует IDisposable. Они не реализовали бы его, если бы это было необязательно.

+0

Я почти остановился, чтобы не щелкнуть, чтобы перейти вверх, когда я прочитал «они не реализовали бы его, если бы это было необязательно», потому что, как пример, все, что я прочитал, говорит, что в Linq to SQL не обязательно «DataContext» 'объект. Есть также помощники ASP.NET MVC, которые используют его как немного синтаксического инструментария, но это совсем не обязательно; такой как объект, возвращаемый 'Html.BeginForm'; все это происходит, когда Disposed выводит конец формы. +1 в любом случае, вообще-то, хороший совет. –

+1

@AndrewBarber - По этому определению никогда не нужно «вызывать» dispose, поскольку GC в конечном итоге вызовет его. Однако то, что я должен был сказать, было «очень желательным», учитывая, что никто не знает, когда Dispose в конечном итоге будет вызван. –

+0

То, что вы сказали о важности вызова 'Dispose' или использования' using', является очень важным и отличным советом, поэтому я не хочу, чтобы он, как правило, был против него. Тем не менее, на самом деле * не * желательно назвать его в некоторых случаях с помощью помощников MVC, которые я отмечаю, например, когда вы выставляете закрывающий тег '' вручную. Предоставляется; Я никогда не использовал этих (или подобных) помощников и не использовал синтаксис 'using', связанный с ними. –

5

Тип MailMessage имеет несколько полей, которые он владеет и которые реализуют IDisposable. Для правильной реализации шаблона IDisposable требуется, чтобы он также реализовал IDisposable и привязал вызов к этим полям. В частности, вложения, виды и вид тела

0

Исходный код можно просмотреть, чтобы узнать, что именно он делает. См. MailMessage.Dispose. Я не включил здесь исходный код, потому что не знаю, разрешено ли это.

+0

На самом деле это не ответ. Вам не нужно публиковать код; просто объясните, почему это необходимо ... так что просто подведите итог тому, что он делает. –

+0

@AndrewBarber, мой исходный код был более авторитетным и современным, чем декомпилированный код в принятом ответе. Поэтому, если кто-то хочет видеть сам, ссылка в этом ответе - быстрый способ сделать это. – Sam

+1

Наверное, да. И это было бы превосходно, как комментарий к принятому ответу или вопросу. Или, вероятно, есть пара отличных дополнительных данных, которые вы могли бы добавить из этого. Это сказало; это * * полезная информация, связанная с этой темой, поэтому я рекомендовал добавить некоторую информацию :) –