网站上耗时的任务
本文关键字:任务 网站 | 更新日期: 2023-09-27 18:14:24
我的asp.net mvc 5项目,有一个页面,用户提交一个帖子,并收到一封关于他们刚刚发表的帖子的电子邮件。我如何构建我的程序,让用户看到一个网页,确认帖子已经立即发布,然后服务器发送一个单独的电子邮件?
这是我想到的:使用2个控制器动作。当确认页面加载时,它通过javascript调用发送电子邮件操作?有没有更好的解决方案?
电子邮件服务也可能会失败,但这不应该影响确认页面
更新2:它应该执行1,然后立即返回。2的状态并不重要async的语法是什么?
public async Task<ActionResult> Confirm(string text)
{
//1. Save post to database
//2. Send email async
return View();
}
如果我不关心交货失败,这就是我所需要的吗?
您可以使用SmtpClient.SendAsync()直接从控制器异步发送消息,假设您依赖System.Net.Mail
作为提供者而不是外部扩展。
控制器语法示例:
[HttpPost]
public ActionResult PostData(object data)
{
//1. Save your post data here...
MailMessage myMessage = new MailMessage();
//2. Play with your message object here...
SmtpClient myClient = new SmtpClient("your.smtp.com", 587);
myClient.SendAsync(myMessage, "myToken");
return View();
}
你必须用Javascript处理视图中的返回值,如果你以后关心这些的话。
我不得不同意@ highc的观点——一封确认邮件,甚至是一个包含少量数据的HTML消息,都不应该花太长时间发送,以至于你需要担心异步操作。您可以通过执行以下操作来包含确认发送的邮件的原始请求:
[HttpPost]
public ActionResult PostData(object data)
{
//...Save your post data here...
MailMessage myMessage = new MailMessage();
//...Play with your message object here...
SmtpClient myClient = new SmtpClient("your.smtp.com", 587);
bool sentOk = true;
try
{
myClient.Send(myMessage);
}
catch
{
sentOk = false;
}
return RedirectToAction("PostConfirmed", new { confirmEmail = sentOk });
}
你可以做任何你想要生成的"PostConfirmed"视图,你可以使用confirmEmail
布尔值来调整视图的内容取决于一个电子邮件错误。
这里也有一些关于async
请求的更深入的信息。
EDIT:根据您对@HighCs关于连接失败的评论,考虑在您的SmtpClient
配置中实现此功能:SmtpClient.Timeout()
你的标题是误导,因为发送电子邮件并不是一个真正耗时的任务,除非你希望发送大附件或做其他处理,以创建电子邮件的内容。根据我在大多数服务器上的经验,一封电子邮件以毫秒为单位发送。
对于您的示例,不需要添加两个控制器动作,也不需要异步。
你可以通过创建一个常规的动作来完成你想要的:
[HttpPost]
public ActionResult PostMessage(string messageText)
{
string result;
try
{
// mail.Send() here
// can use SendAsync but then need to handle result feedback via JavaScript
result = "Email was sent";
}
catch
{
result = "Sending Email Failed";
}
return View("PostConfirmation", result);
}
编辑:如果你有不可靠的网络,我会异步发送电子邮件,并在你的确认屏幕上显示"邮件排队"。
如果你想远离JavaScript轮询,那么只需在你的动作开始时存储来自后台任务的消息,例如:ViewBag。AsynchMessage = "你的帖子是通过电子邮件发送的"。只要将ViewBag包含在主布局中合适的位置,用户就可以在处理消息时看到它们。不要忘记在随后的请求中清空ViewBag,以保持UI的整洁。
如果您不想等待数据库保存和邮件发送,您可以创建一个任务并立即返回:
public ActionResult PostData(string text)
{
//1. Save post to database
var databaseTask = Task.Factory.StartNew(this.SavePostToDatabase);
//2. Send email async
databaseTask.ContinueWith(task => this.SendEmail());
//3. Confirmation view
return RedirectToAction("PostConfirmed");
}
protected void SendEmail()
{
throw new NotImplementedException();
}
private void SavePostToDatabase()
{
throw new NotImplementedException();
}