So, I'm trying to send an email as a notification to the user, and I want it to run asynchronously . I originally implemented with Task.Factory.StartNew as shown below:
Task.Factory.StartNew(() => { _notify.NotifyUser(params); });
NotifyUser is a void method that actually sends an email to the user.
But he never performed this method. I put the log message method inside NotifyUser , which was never logged.
I followed this post and found out that
Sometimes this behavior is a sign of an overloaded ThreadPool. Given that these are long running / blocking tasks, they cannot be run in ThreadPool, where Task.Factory.StartNew will send them using the default TaskScheduler
and therefore I followed what was suggested there, which is given below:
ThreadStart action=()=>{ _notify.NotifyUser(params); }; Thread thread=new Thread(action){IsBackground=true}; thread.Start();
I did not find luck in the above approach. Again, I followed another approach that didn't even work.
Task task = new Task(() => { _notify.NotifyUser(params); }); task.RunSynchronously(); //or task.Start();
Is there any other way to run this task to send email? I heard about async await , but I read that it will not be used on void methods . Can someone tell me what would be the best approach here?
Update
ThreadPool.QueueUserWorkItem(t => { _notify.NotifyUser(params); });
so that it executes this method when the stream is available. But so far we are out of luck.
Actual code
[HttpPost] [ValidateAntiForgeryToken] public ActionResult AddEditUser(UVModel model) { if (HasPermission()) { string message = string.Empty; bool success = false; string returnUrl = string.Empty; if (ModelState.IsValid) { using (_db = new EFDB()) { //fill user model _db.Entry(user).State = state; _db.SaveChanges(); _notify = new SendNotification(); _notify.NotifyUser(params); //This has to be asynchronous success = true; returnUrl = Url.Action("Action", "Controller", null, HttpContext.Request.Url.Scheme, HttpContext.Request.Url.Host); message="success"; } } else message = "Server side validation failed!"; return Json(new { result = success, message = message, redirectUrl = returnUrl }, JsonRequestBehavior.AllowGet); } else return Json(new { result = false, message = "You do not have permission to perform this action!", redirectUrl = "" }, JsonRequestBehavior.AllowGet); }
SendNotification.cs
public void NotifyUser(Parameter params) { using (MailMessage mail = new MailMessage()) { _db = new EFDB(); mail.To.Add(params.toAddress); mail.From = params.from; mail.Subject = params.subject; mail.Body = params.body; mail.IsBodyHtml = true; mail.Priority = MailPriority.High; SmtpClient smtp = new SmtpClient(); smtp.Host = "some smtp host"; smtp.Port = 25; smtp.UseDefaultCredentials = false; smtp.EnableSsl = false; smtp.Credentials = new NetworkCredential("uname", "pwd"); smtp.DeliveryMethod = SmtpDeliveryMethod.Network; try { smtp.Send(mail); } catch (SmtpFailedRecipientException se) { LogError.LogMessage("SmtpFailedRecipientException Exception - " + se.Message.ToString(), context); } catch (SmtpException se) { LogError.LogMessage("SmtpException - " + se.Message.ToString(), context); } } }