我有一个执行任务的控制器操作,最后,它会向用户发送一封确认电子邮件。它的电子邮件部分不是很重要,所以如果发送电子邮件引发异常,我不想让我的行动中断,我不希望我的HTTP响应等待e - 要发送的邮件。我希望这是一场火灾而忘记的事情。
简而言之,这就是我接近它的方式:
public async Task<ActionResult> MyAction(){
// Do stuff
await DoStuff();
Thread sendEmailThread = new Thread(SendEmail);
sendEmailThread.Start();
return result;
}
private async void SendEmail(){
await smtpClient.SendMessageAsync();
}
这种做法是否合适?
答案 0 :(得分:1)
每当收到新电子邮件时,启动新线程并不是一个好主意。
我们通常在应用程序后面运行后台调度系统。例如,Quartz.NET
然后我们将队列(或数据库)中的电子邮件排队,让后台线程从队列(或数据库)中获取,并预先形成该过程。
通过这样做,如果SMTP出错,我们可以重新发送电子邮件。
答案 1 :(得分:0)
没有必要启动一个新线程来发送电子邮件,因为一旦async
操作开始,该方法就会返回,并且线程将在操作完成之前结束。
异步操作do not use a thread因此您最好只从该方法返回Task
并await
。异步void
返回方法是一个坏主意,并且没有异常传播出来,你无法分辨操作何时完成。有关详细信息,请参阅Best Practices in Async programming。
如果您真的想要解雇并忘记任务,请参阅主题Stephen Cleary's blog。
答案 2 :(得分:0)
我无法为您提供直接的解决方案,但火灾和忘记的事情是通过asp.net的开源电子商务解决方案实现的,并称为nopCommerce。我真的很喜欢他们的解决方案,我只是想和你分享。
这是codeplex代码;
转到 Src - &gt;图书馆 - &gt; Nop.Services - &gt;任务
https://nopcommerce.codeplex.com/SourceControl/latest#src/Libraries/Nop.Services/Tasks/TaskManager.cs
现在看看TaskManager类。您可以在线查看演示here。
转到管理员面板 - &gt;系统菜单 - &gt;安排任务
他们使用此类作为队列电子邮件,保持活跃,清除缓存,自动更新汇率以及删除许多其他内容。它完全符合您的要求。如果发生任何异常,它只会重试,它不会停止或破坏应用程序。你可以查看演示。