I have a small console application. It checks a few settings, makes some decisions, and sends an email. The problem is the email doesn't actually get sent until my application finishes. I want the email sent as soon as my method that sends the email completes.
Initially, I just created a MailMessage and called .Send(). That's when I noticed the mail was not being sent until the app finished.
Then I tried using the task parallel library.
var taskA = Task.Factory.StartNew(() => msg.Send());
Again, the messages don't get sent until my entire application finishes.
How do I sent an email when msg.send executes, not when the app completes?
SmptClient supports async sending of mail via SendAsync, however in practice in a web application this hangs the request thread.
To avoid blocking I recommend using the ThreadPool to fire off the email in a background thread. This won't block your application.
ThreadPool.QueueUserWorkItem(o => {
using (SmtpClient client = new SmtpClient(...))
{
using (MailMessage mailMessage = new MailMessage(...))
{
client.Send(mailMessage, Tuple.Create(client, mailMessage));
}
}
});
The most sure fire way to avoid delays would probably be to use a pickup directory, which will queue the message rather than send it immediately.
you should use a SMTP client. do it like this:
MailMessage mm = new MailMessage();
//fill in your message
NetworkCredential nc = new NetworkCredential(FromAddress, FromPassword);
SmtpClient sc = new SmtpClient(SmtpHost, SmtpPort);
sc.EnableSsl = true;
sc.Credentials = nc;
sc.Send(mm);
at this stage your mail will be sent.
But, sending an email is an async act, so it will take some time until you recive the mail.
Create a new MailMessage and send it with SmtpClient. It will send immediately. I will add an example.
EDIT: Populate the variables host, port with the smtp ser ver name and port number.
using (var mailer = new SmtpClient(host, port))
{
using (var message = new MailMessage(sender, recipient, subject, body) { IsBodyHtml = false })
{
mailer.UseDefaultCredentials = false;
mailer.Credentials = new NetworkCredential(user, pass);
mailer.EnableSsl = useSSL;
mailer.Timeout = Timeout;
mailer.Send(message);
}
}
If you still experience a delay, then the delay will be at the mail server.
Simply dispose the MailMessage and SmtpClient objects after the .Send() function.
SmtpClient smtpClient = new SmtpClient("server", 25);
smtpClient.UseDefaultCredentials = true;
MailMessage message = new MailMessage("ToAddress","FromAddress");
message.Subject = "Test email";
message.Body = "Test email";
smtpClient.Send(message);
message.Dispose();
smtpClient.Dispose();
Use SmtpClient with setting:
smtpClient.ServicePoint.MaxIdleTime = 2;
https://weblogs.asp.net/stanleygu/tip-14-solve-smtpclient-issues-of-delayed-email-and-high-cpu-usage
Related
when my asp's service sends email by IEmailSender, sometime google blocks my service. This is my configuration:
public Task SendEmailAsync(string email, string subject, string message)
{
SmtpClient client = new SmtpClient(_configuration["MailSettings:Server"])
{
EnableSsl = bool.Parse(_configuration["MailSettings:EnableSsl"]),
UseDefaultCredentials = false,
Credentials = new NetworkCredential(_configuration["MailSettings:UserName"], _configuration["MailSettings:Password"]),
Port = int.Parse(_configuration["MailSettings:Port"]),
};
MailMessage mailMessage = new MailMessage
{
From = new MailAddress(_configuration["MailSettings:FromEmail"], _configuration["MailSettings:FromName"]),
};
mailMessage.To.Add(email);
mailMessage.Body = message;
mailMessage.Subject = subject;
mailMessage.IsBodyHtml = true;
client.Send(mailMessage);
return Task.CompletedTask;
}
And google make me can not send email sometimes:
When I allow this server, my service can send email normally. After short time, google blocks me again and again.I want my service can send an email everytime no need to check mail and allow this server to use my email account. Please help me. Thanks so much.
I have a program for sending my resume to emails of people who posted jobs if they included their email in their post.
so I send an email with their quote of the job description, date of when it was generated etc,
so each email is unique, But each email uploads the same file (resume.pdf) as Attachment.
right now each time I send an email I need to upload the same file (resume.pdf) // my resume
so this are my questions:
can I send each email and only upload my pdf resume once?
right now I use a smtp client library like this:
GMailSmtp gmail = new GMailSmtp(new NetworkCredential("username", "password"));
so each time I send an email I create a thread that opens a new connection which seems time consuming to me.
I was wondering if there is an API or library to create 1 connection and then send all the emails I want thru a queue or create a new thread just for sending the email.
Yes. If you're using a third-party server like Gmail, you will need to upload your resume with each email. BUT, there are lots of easy ways to do this in the background.
Play with this for a while and if you have specific questions or problems, post your code and your specific issue:
List<string> recipients = new List<string>();
BackgroundWorker emailer = new BackgroundWorker();
public void startSending()
{
emailer.DoWork += sendEmails;
emailer.RunWorkerAsync();
}
private void sendEmails(object sender, DoWorkEventArgs e)
{
string attachmentPath = #"path to your PDF";
string subject = "Give me a JOB!";
string bodyHTML = "html or plain text = up to you";
foreach (string recipient in recipients)
{
sendEmail(recipient, subject,bodyHTML,attachmentPath);
}
}
private void sendEmail(string recipientAddress, string subject, string bodyHTML,string pathToAttachmentFile)
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
mail.From = new MailAddress("your_email_address#gmail.com");
mail.To.Add(recipientAddress);
mail.Subject = subject;
mail.Body = bodyHTML;
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment(pathToAttachmentFile);
mail.Attachments.Add(attachment);
SmtpServer.Port = 587;
SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
SmtpServer.EnableSsl = true;
SmtpServer.Send(mail);
}
Note that BackgroundWorker requires a reference to System.ComponentModel.
You could use separate thread for sending e-mails. For example you can do it as Shannon Holsinger suggested. You could also upload your resume to Dropbox or anywhere else and send the link instead of attaching a file.
I'm trying to send email from asp.net mvc controller. Gmail account used here for smpt is configured to use with less security, so that's not the problem here.
but I don't get any error message neither any exception, but it not
deliver at my expected email address.
I'm using code
var text = "email body to deliver";
SendEmail("mydeliverEmailAddress#gmail.com", text);
public static bool SendEmail(string SentTo, string Text)
{
SmtpClient client = new SmtpClient();
client.Credentials = new NetworkCredential("myemail#gmail.com", "myGmailPass");
client.Port = 465;
client.Host = "smtp.gmail.com";
client.EnableSsl = true;
try
{
MailAddress
maFrom = new MailAddress("sender_email#domain.tld", "Sender's Name", Encoding.UTF8),
maTo = new MailAddress(SentTo, "Recipient's Name", Encoding.UTF8);
MailMessage mmsg = new MailMessage(maFrom.Address, maTo.Address);
mmsg.Body = "<html><body><h1>Some HTML Text for Test as BODY</h1></body></html>";
mmsg.IsBodyHtml = true;
mmsg.Subject = "Some Other Text as Subject";
mmsg.SubjectEncoding = Encoding.UTF8;
client.Send(mmsg);
}
catch (Exception ex)
{
}
return true;
}
Wait a minute. You are using your gmail account: myemail#gmail.com and trying to send an email on behalf of sender_email#domain.tld?
For more than obvious reasons that's never gonna work. So make sure that you are using the same email address as the one you are authenticating against:
maFrom = new MailAddress("myemail#gmail.com", "Sender's Name", Encoding.UTF8),
You can only send emails from the account you are authenticated against. Of course the recipient email can be any address that gmail can deliver to.
You've got another issue with your code. You are using a wring port here:
client.Port = 465;
The correct port that gmail SMTP works with is the following:
client.Port = 587;
Also you might want to ensure that you have enabled less secure apps in your gmail account or you will not be able to use SmtpClient in .NET to send emails using this SMTP: https://www.google.com/settings/security/lesssecureapps?pli=1
but I don't get any error message neither any exception, but it not
deliver at my expected email address.
What error message do you expect to get when you did the worst ever possible thing? You wrapped your code in a try/catch block and in your catch block you did absolutely nothing. You just consumed the exception:
catch (Exception ex)
{
}
So make sure that you do something useful with an exception if you are going to be catching it. For example something useful could be to log this exception and send an error message to the user saying that something bad happened and you couldn't send an email and that you are investigating the issue right now.
var smtpClient = new SmtpClient("YourSMTPServer", "SMTPServerPort"))
{
Credentials = new NetworkCredential("YourEmail",
"Password"),
EnableSsl = false
};
string fromEmail = "YourEmail";
var mailMessage = new MailMessage();
mailMessage.From = new MailAddress(fromEmail);
mailMessage.To.Add("Recipient's EMail");
mailMessage.Subject = "Test Mail";
mailMessage.Body = "This is test Mail";
mailMessage.IsBodyHtml = true;
smtpClient.Send(mailMessage);
I am trying to make an email sender by C#. I have used System.Net.Mail to do that. But after doing all the thing when I am going to send the mail using SmtpClient's Send() method it throws me exception. why?
code is here
MailMessage mail = new MailMessage("wtushar_09#live.com", "wtushar09#gmail.com");
SmtpClient sc = new SmtpClient("smpt.live.com");
sc.Port = 587;
sc.Credentials = new System.Net.NetworkCredential("wtushar_09#live.com", "************");
sc.EnableSsl = true;
sc.Send(mail);
MessageBox.Show("Mail sent", "done", MessageBoxButtons.OK);
exception is coming from sc.Send(mail);
SmtpClient sc = new SmtpClient("smpt.live.com");
Your SMTP server name is likely wrong. Should probably be smtp.live.com.
I think i need some guru lights!
public void SendEndingMail(string fileName)
{
SmtpClient client;
client = new SmtpClient("smtp.myserver.com", 25);
//client = new SmtpClient();
if (!string.IsNullOrEmpty(""))
{
System.Net.NetworkCredential credential = new NetworkCredential("", "");
client.Credentials = credential;
}
client.UseDefaultCredentials = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
//client.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
MailAddress fromAddress = new MailAddress("mailing#mydom.com", "Elec");
MailAddress toAdrress = new MailAddress("mailing#mydom.com");
using (System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage(fromAddress, toAdrress))
{
mailMessage.Attachments.Add(new System.Net.Mail.Attachment(fileName));
mailMessage.IsBodyHtml = false;
mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
try
{
client.Send(mailMessage);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
}
Is that true that:
when i set
client.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
It does not matter whichever smtp server i use
client = new SmtpClient("smtp.myserver.com", 25);
//client = new SmtpClient();
The both lines are the same since it will use LOCAL IIS ?!!!
Is this is true, it is not normal that the API is build this way!? it is very confusing...
Thanks
Jonathan
IIRC, when the SmtpClient sends the email, it looks at the .DeliveryMethod value. If the value is Network, then it sends via network. If it is PickupDirectoryFromIis, then it ignores any specified SMTP server (because it just writes and the email to the filesystem), and writes it to the Pickup directory. No network communication takes place.
That is a bug in the Send routine - it creates an smtp server object even if one isn't specified, and when it later (after Send) tries to dispose it, it throws an exception. This happens AFTER the mail is successfully placed in the pickup directory, so the mail will be sent.
Workarounds:
Specify localhost as SMTP server. It won't be used, but prevents the exception.
A blind try/catch around the Send method (BAD solution).