0

我有一个执行任务的控制器操作,最后,它会向用户发送一封确认电子邮件。它的电子邮件部分不是很重要,所以如果电子邮件的发送抛出异常,我不想让我的动作中断,我不希望我的 HTTP 响应等待电子邮件发送。我希望这是一场火灾,然后忘记事情。

简而言之,这就是我的处理方式:

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


这种方法合适吗?

4

3 回答 3

1

每当收到新电子邮件时就开始新线程不是一个好主意。

替代方法(尤其是电子邮件)

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

然后我们在队列(或数据库)中排队电子邮件,并让后台线程从队列(或数据库)中提取,并执行该过程。

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

于 2014-10-23T00:06:37.013 回答
0

我不能给你一个直接的解决方案,但火和忘记的事情是由 asp.net 的开源电子商务解决方案实现的,称为 nopCommerce。我真的很喜欢他们的解决方案,我只是想与您分享。
这是codeplex代码;
转到Src -> 库 -> Nop.Services -> 任务
https://nopcommerce.codeplex.com/SourceControl/latest#src/Libraries/Nop.Services/Tasks/TaskManager.cs
现在看看 TaskManager 类。您可以在此处在线查看演示。转到管理面板 -> 系统菜单 -> 计划任务

解释

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

于 2014-10-23T05:42:41.567 回答
0

无需启动新线程来发送电子邮件,因为该方法将在async操作开始后立即返回,并且该线程将在操作完成之前结束。

异步操作不使用线程,因此您最好只Task从该方法返回 a 并返回await它。异步void返回方法是一个坏主意,并且没有异常从它们传播出来,您无法判断操作何时完成。有关更多详细信息,请参阅异步编程中的最佳实践。

如果您真的想完成一项“一劳永逸”的任务,请参阅Stephen Cleary 的有关该主题的博客。

于 2014-10-23T01:00:57.383 回答