Это проблема, которую я недавно решил, но задавался вопросом, может ли кто-нибудь помочь мне разобраться в этом, потому что я не совсем понимаю, что именно произошло. Я создал простой почтовый клиент smtp и завернул его в оператор using, чтобы избавиться от него. Внутри электронной почты я добавил приложение PDF файла, которое я создал на лету. Как только письмо было отправлено, я хотел уничтожить PDF, так как он был временно сохранен локально на машине, чтобы отправить электронное письмо. Когда будет выполняться метод File.Delete(), я получаю сообщение об ошибке, что рабочий процесс IIS блокировал файл. Я не мог понять, почему, поскольку мой клиент уже был удален, прежде чем я попытался удалить файл. Наконец, я узнал, что мне пришлось также удалить приложение, прежде чем я смогу удалить файл. Итак, мой вопрос заключается в том, почему не распоряжается клиент, также избавляясь от приложения? Разве это не часть приложения клиента, поэтому она должна быть удалена после того, как клиент будет удален? Пример кода ниже:
try
{
using (SmtpClient SmtpMail = new SmtpClient(""))
{
MailMessage message = new MailMessage(From, To, Subject, Body);
message.IsBodyHtml = false;
message.Priority = MailPriority.Normal;
Attachment attachment = new Attachment(pdfString);
message.Attachments.Add(attachment);
SmtpMail.Send(message);
attachment.Dispose(); //Why is this needed?
}
}
Метод SmtpClient Send()
не отвечает (и не должен) за удаление MailMessage (и связанных с ним активов). SmtpClient не может сделать предположение о предполагаемом использовании MailMessage после его отправки. Возможно, вы захотите продолжить использование потока MailMessage или вложения для других целей.
Рассмотрим случай, когда экземпляр MailMessage будет повторно использоваться несколькими SmtpClients.
var message = new MailMessage();
using(var client1 = new SmtpClient())
{
client1.Send(message);
}
...
using(var client2 = new SmtpClient())
{
client2.Send(message);
}
Если message
вложения уже были захоронены после первого вызова, второй вызов потерпит неудачу.
Было бы неправильно, если бы SmtpClient просто предположил, что вы закончили с MailMessage после того, как вы его отправили в первый раз. Метод Send()
должен отправить электронное письмо, а не отправлять и также удалять активы сообщения. Возможно, вашей программе потребовалась дальнейшая работа с потоком вложения позже в программе.