加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 托管到服务器时,任务或线程无法工作/运行

发布时间:2020-12-16 03:17:22 所属栏目:asp.Net 来源:网络整理
导读:所以我试图将电子邮件作为通知发送给用户,我希望它以异步方式运行.最初我用Task.Factory.StartNew实现如下: Task.Factory.StartNew(() = { _notify.NotifyUser(params); }); NotifyUser是一种实际向用户发送电子邮件的void方法. 但它从未执行过该方法.我在N
所以我试图将电子邮件作为通知发送给用户,我希望它以异步方式运行.最初我用Task.Factory.StartNew实现如下:

Task.Factory.StartNew(() => { _notify.NotifyUser(params); });

NotifyUser是一种实际向用户发送电子邮件的void方法.

但它从未执行过该方法.我在NotifyUser方法中放置了一条日志消息,该方法从未被记录.

我跟着this post了解了

Sometimes this kind of behaviour is an indication of an overloaded ThreadPool. Seeing as these are long running/blocking tasks,they should not be scheduled to run in the ThreadPool,which is where Task.Factory.StartNew will be sending them using the default TaskScheduler

所以我按照那里的建议进行了如下操作:

ThreadStart action=()=>{
    _notify.NotifyUser(params);
};
Thread thread=new Thread(action){IsBackground=true};
thread.Start();

上述方法也没有运气.我再次采用了一种甚至不起作用的方法.

Task task = new Task(() => {
     _notify.NotifyUser(params); 
});
task.RunSynchronously(); //or task.Start();

有没有其他方法可以运行发送电子邮件的任务?我听说异步等待,但我读到它不会用于void方法.有人能告诉我这里最好的方法是什么吗?

更新

ThreadPool.QueueUserWorkItem(t =>
{
   _notify.NotifyUser(params); 
});

这样当线程可用时它将执行此方法.但这里仍然没有运气.

实际代码

[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);
            }
    }
}

解决方法

You should never use StartNew unless you’re doing dynamic task-based parallelism.我在博客上解释了为什么难以理解的细节.

假设您在ASP.NET上运行,则应使用HostingEnvironment.QueueBackgroundWorkItem.我怀疑你看到了你的委托的异常,QBWI会记录事件日志的任何异常.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读