Application requires that a use SendAsync rather than just Send. So i Made a Class CEmailServer and set up everything. So far Send works fine but when changing it to work with SendAsync it does not. I Created a Method to be called when a mail is sent and the userToken is in place but it keeps failing. i Can't find my error. Here is my code :
static bool mailSent = false;
//Method for Sending with attachment.
public void SendEmail(string Address, string Recipient, string Subject, string Body, string Dir)
{
var fromAddress = new MailAddress("[email protected]", "My Company");
var toAddress = new MailAddress(Address, Recipient);
const string fromPassword = "password";
string subject = Subject;
string body = Body;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
})
{
smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
string userState = "Test";
message.Attachments.Add(new Attachment(Dir));
smtp.SendAsync(message,userState);
message.Dispose();
}
}
//Method for Sending regular message without attachment.
public void SendEmail(string Address, string Recipient, string Subject, string Body)
{
var fromAddress = new MailAddress("[email protected]", "My Company");
var toAddress = new MailAddress(Address, Recipient);
const string fromPassword = "password";
string subject = Subject;
string body = Body;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
})
{
smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
string userState = "Message Sent";
smtp.SendAsync(message, userState);
message.Dispose();
}
}
//Method to be called when sending is complete
private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
if (e.Cancelled)
{
MessageBox.Show("Sending Canc");
}
if (e.Error != null)
{
MessageBox.Show("Error Sending Mail");
}
else
{
MessageBox.Show("Message sent.");
}
mailSent = true;
}
Thank you very much!
You are disposing the message
before the send can complete. You should be disposing them in the SendCompleted
callback event. Here's an example of the best way to dispose the client and the message.
Your code should look something like this:
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body,
};
smtp.SendCompleted += (s, e) => {
SendCompletedCallback(s, e);
smtp.Dispose();
message.Dispose();
};
string userState = "Test";
message.Attachments.Add(new Attachment(Dir));
smtp.SendAsync(message, userState);