来自Application_Error()的异步调用

时间:2016-01-27 13:52:23

标签: c# asp.net-mvc-5

我试图弄清楚如何从MVC中的Application_Error方法创建异步调用。

我有一个我写过的电子邮件dll,它使用Smtp客户端通过异步调用发送电子邮件。

问题是当我在我的dll中调用SendEmail方法时,我需要等待调用的冲突。现在,如果我尝试这样的事情:

protected async void Application_Error()
{
    var await emailService.SendEmail("Hello World");
}

它不起作用,甚至不会调用该方法。

我可以通过同步方法进行异步调用吗?我在网上的研究暗示HttpServerUtility.TransferRequest可能是答案,但我无法弄清楚如何使它符合我的要求,这对我来说只是没有意义。

2 个答案:

答案 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));
}