这个MVC Fire和Forget接近糟糕的设计吗?

时间:2014-10-22 23:42:15

标签: asp.net-mvc email asynchronous fire-and-forget

我有一个执行任务的控制器操作,最后,它会向用户发送一封确认电子邮件。它的电子邮件部分不是很重要,所以如果发送电子邮件引发异常,我不想让我的行动中断,我不希望我的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();
}


这种做法是否合适?

3 个答案:

答案 0 :(得分:1)

每当收到新电子邮件时,启动新线程并不是一个好主意。

替代方法(特别是电子邮件)

我们通常在应用程序后面运行后台调度系统。例如,Quartz.NET

然后我们将队列(或数据库)中的电子邮件排队,让后台线程从队列(或数据库)中获取,并预先形成该过程。

通过这样做,如果SMTP出错,我们可以重新发送电子邮件。

答案 1 :(得分:0)

没有必要启动一个新线程来发送电子邮件,因为一旦async操作开始,该方法就会返回,并且线程将在操作完成之前结束。

异步操作do not use a thread因此您最好只从该方法返回Taskawait。异步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;安排任务

解释

他们使用此类作为队列电子邮件,保持活跃,清除缓存,自动更新汇率以及删除许多其他内容。它完全符合您的要求。如果发生任何异常,它只会重试,它不会停止或破坏应用程序。你可以查看演示。