m.r*_*fca 1 c# asp.net-mvc async-await
我正在尝试从Controller发送电子邮件异步并收到以下错误:
我不希望等待电子邮件发送给完成动作.
在异步操作仍处于挂起状态时完成异步模块或处理程序.
这是我实现我使用还试图void代替async Task
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
var user = await _userManager.FindByNameAsync(model.Email);
if (user != null)
{
if (!await _userManager.IsEmailConfirmedAsync(user.Id))
{
//dont want to await result
//just send email
_mailService.SendAccountConfirmationEmailAsync(user);
...
}
...
}
return View();
}
Run Code Online (Sandbox Code Playgroud)
.
public async Task SendAccountConfirmationEmailAsync(ApplicationUser user)
{
dynamic email = GetAccountConfirmationEmailTemplate();
email.Username = user.Email;
email.Name = user.UserName;
email.To = user.Email;
email.AccountConfirmationUrl = await GetAccountConfirmationUrl(user);
await _mailService.SendAsync(email);
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
由于运行时可以在知道没有更多待处理请求时回收您的应用程序域,因此特别不推荐您不等待的启动任务,因此该消息.
特别是,如果没有此检查,您将无法保证此电子邮件将被发送,因为在您的控制器操作返回后,整个应用程序域可能会被围绕该任务拉下来.
现在在你的情况下,你可能会说丢失电子邮件是可以接受的,但是运行时不知道它只是一封电子邮件,很可能是你忘记等待的数据库调用过早了中止.因此,它只是告诉你这是不好的形式.
相反,你有两个选择:
最后一部分是HostingEnvironment.QueueBackgroundWorkItem的用途.
在你的情况下你会这样称呼它:
HostingEnvironment.QueueBackgroundWorkItem(ct =>
_mailService.SendAccountConfirmationEmailAsync(user));
Run Code Online (Sandbox Code Playgroud)
另外,该方法提供了一个CancellationToken,您应该检查是否存在SendAccountConfirmationEmailAsync接受它的重载.如果没有,如果这是您的API,您应该考虑添加对此类令牌的支持.
请注意,此机制不适用于长时间运行的线程或任务,因为还有其他更合适的树可以树立,但在这种情况下它应该足够了.
| 归档时间: |
|
| 查看次数: |
1465 次 |
| 最近记录: |