我试图弄清楚如何从MVC中的Application_Error方法创建异步调用。
我有一个我写过的电子邮件dll,它使用Smtp客户端通过异步调用发送电子邮件。
问题是当我在我的dll中调用SendEmail方法时,我需要等待调用的冲突。现在,如果我尝试这样的事情:
protected async void Application_Error()
{
var await emailService.SendEmail("Hello World");
}
它不起作用,甚至不会调用该方法。
我可以通过同步方法进行异步调用吗?我在网上的研究暗示HttpServerUtility.TransferRequest
可能是答案,但我无法弄清楚如何使它符合我的要求,这对我来说只是没有意义。
答案 0 :(得分:2)
dll的限制,我无法改变它。
我不知道为什么异步通话不会发送电子邮件。这应该。某处有一个错误。
但是解决方法是:
Task.Run(async () => { await emailService.SendEmail("Hello World"); }).Wait();
您可以简化和优化这一点,但这是实现这一想法的最简单方法。此模式始终是同步调用异步方法的安全方法。对于perf来说并不好,但这并不重要,因为发送电子邮件比开销高出1000倍。
如果要保留异步行为,可以删除Wait
。虽然在那一点上我想知道为什么发送不起作用。是异步行为触发的错误还是总是在那里?!
答案 1 :(得分:2)
对于那些可能在未来遇到此问题的人,这里有另一种可能更强大的解决方案。您可以使用ThreadPool.QueueUserWorkItem()
而不是HostingEnvironment.QueueBackgroundWorkItem()
。这样做,要求服务器在关闭之前完成这些任务。
以下是最近项目的一个例子:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
HostingEnvironment.QueueBackgroundWorkItem(ct =>
ExceptionLogger.LogAsync(ex));
}