Reputation: 41
I have a problem I've not run into before, and can't seem to find any similar issues when I search.
My issue is this.
I have an email method which attaches a PDF using a memory stream, then sends the email using the SendAsync method. Very rarely though, the attachment is attached to a different users email.
This has only happened on extremely rare occasions, and seems to be caused when two emails are sent at exactly the same moment, and even then it's rare that it happens.
The problem is that, no matter how rare, it should not be happening so I'd like to fix it.
The PDF is generated by downloading the results of a URL which returns a PDF, into a WebClient object, then using reading the results of the WebClient.DownloadData method into a memory stream. The memory stream is then attached to an MailMessage object and sent using an SMTPClient object's SendAsync method.
As I said, the problem occurs very infrequently, unfortunately making it very difficult to test.
Here is an example of my code (no actual values, just an example of how it is created, in a cut down way, ie no error trapping etc):
var mailMessage = new MailMessage("[email protected]", "[email protected]", "Subject");
var smtpClient = new SmtpClient();
mailMessage.Body = "Test";
var stream = new MemoryStream(new WebClient().DownloadData("test.com"));
var attachment = new Attachment(stream, "filename.pdf", System.Net.Mime.MediaTypeNames.Application.Pdf);
mailMessage.Attachments.Add(attachment);
smtpClient.SendCompleted += new SendCompletedEventHandler(SendCompleteCallback); // this is a method for logging errors etc
smtpClient.SendAsync(mailMessage, "randomGuidToken");
When the problem does happen, only the user who receives both attachments actually gets an email. The other user gets nothing, no email or attachment.
All help is appreciated.
Upvotes: 1
Views: 369
Reputation: 41
I've managed to solve my issue.
It was down to how the SmtpClient and MailMessage classes were being instantiated and disposed of (or not, in this case).
I found out that the original code was creating the SmtpClient and MailMessage objects as a class wide variable, which was initialised in the class constructor, and the only code which handled the disposing of the objects was in the SendAsynCompleted callback method.
I have now changed the code so that the SmtpClient and MailMessage objects are instantiated within each method which needs them within the class, and made sure the objects are disposed of explicitly.
I've also moved away from using the SendAsync method for now and just use the standard Send method (I may look at moving back to the async method but will need to do a lot more testing and refactoring I think).
Upvotes: 1