我正在尝试为基于VS2013项目模板的ASP.NET MVC5网站设置电子邮件确认,参考了示例AccountController。我已经使用SmtpClient实现了IIdentityMessageService,尽可能保持简单:
在这种情况下,请求似乎发生了死锁,从未将任何内容返回给客户端。如果邮件由于其他原因(例如主机积极拒绝连接)发送失败,则异常会被正常处理,并且我会收到YSOD。
查看Windows事件日志,似乎在同一时间范围内抛出了一个InvalidOperationException,并显示消息“异步模块或处理程序在仍有异步操作挂起时完成。”; 如果我尝试在控制器中捕获SmtpException并在catch块中返回ViewResult,则会在YSOD中获得相同的消息。因此,我认为await的操作在任何情况下都无法完成。
据我所知,我遵循了在其他SO帖子中概述的所有异步/等待最佳实践(例如HttpClient.GetAsync(...)使用await/async时永远不会返回),主要是“一路使用异步/等待”。我还尝试过使用
我做错了什么吗?我可以始终在SendAsync方法中使用同步调用(即
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using(var client = new SmtpClient())
{
var mailMessage = new MailMessage("some.guy@company.com", message.Destination, message.Subject, message.Body);
await client.SendMailAsync(mailMessage);
}
}
}
调用它的控制器代码直接来自模板(提取为单独的操作,因为我想排除其他可能的原因):
public async Task<ActionResult> TestAsyncEmail()
{
Guid userId = User.Identity.GetUserId();
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userId, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(userId, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
return View();
}
然而,当邮件发送失败时,我遇到了奇怪的行为,但只有在主机不可达的特定情况下才会出现。示例配置:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="unreachablehost" defaultCredentials="true" port="25" />
</smtp>
</mailSettings>
</system.net>
在这种情况下,请求似乎发生了死锁,从未将任何内容返回给客户端。如果邮件由于其他原因(例如主机积极拒绝连接)发送失败,则异常会被正常处理,并且我会收到YSOD。
查看Windows事件日志,似乎在同一时间范围内抛出了一个InvalidOperationException,并显示消息“异步模块或处理程序在仍有异步操作挂起时完成。”; 如果我尝试在控制器中捕获SmtpException并在catch块中返回ViewResult,则会在YSOD中获得相同的消息。因此,我认为await的操作在任何情况下都无法完成。
据我所知,我遵循了在其他SO帖子中概述的所有异步/等待最佳实践(例如HttpClient.GetAsync(...)使用await/async时永远不会返回),主要是“一路使用异步/等待”。我还尝试过使用
ConfigureAwait(false)
,但没有改变。由于代码只有在抛出特定异常时才会死锁,我认为通常情况下模式是正确的,但在这种情况下发生了某些内部问题,但由于我对并发编程相当陌生,我觉得我可能是错的。我做错了什么吗?我可以始终在SendAsync方法中使用同步调用(即
SmtpClient.Send()
),但感觉应该按原样工作。
SendMailAsync
з©әж–№жі•ејӮеёёж–№йқўзҡ„еӣһзӯ”гҖӮејӮжӯҘз©әж–№жі•жңүж—¶дјҡжҲҗдёәй—®йўҳе„ҝз«ҘгҖӮ - Erik Philipsasync void
方法(无论是实现还是调用)- 你是指特定的行吗? - Alexei LevenkovWithNoContext
,从这里获取,看看是否有所不同。 - noseratio - open to work