异常处理在as.net / await调用的asp.net控制器中不起作用

时间:2018-01-17 15:51:54

标签: c# asp.net async-await

我想知道为什么异常处理在asp.net和控制台中对async / await调用的行为有所不同。考虑这种方法:

        private static async Task Test()
        {
            try
            {
                await Task.Run(() =>
                {
                    throw new Exception("Test Exception");
                });
            }
            catch (Exception)
            {
                throw;
            }
        }

Catch没有在IIS下工作的ASP.NET非异步控制器,在Test()和TestAction()中都没有:

    [HttpGet]
    public virtual ActionResult TestAction()
    {
        try
        {
            Test().Wait();
        }
        catch (Exception)
        {
            throw;
        }
     }

而是http请求挂起。相同的控制台代码或WindowsForms代码在两个地方都能正常工作:

class Program
{   
    static void Main(string[] args)
    {           
        try
        {
            Test().Wait();
        }
        catch (Exception)
        {
            throw;
        }
    }
}

更新:

这段代码在asp.net控制器中工作正常(catch被调用):

[HttpGet]
public virtual ActionResult TestAction()
{
        try
        {
            Task.Run(() =>
            {
                throw new Exception("Test Exception");
            }).Wait();
        }
        catch (Exception)
        {
            throw;
        }
  }

1 个答案:

答案 0 :(得分:1)

TestAction()调用Test()同步运行,直到Task.Run....然后await放弃当前线程。 Wait()中的TestAction()现在接受该线程并阻止它直到任务完成。同时,任务抛出并完成。控件应该返回到await之后的行,但它不能,因为它想要将控制权返回给它被调用的线程,该线程被阻塞。因此,僵局。 ConfigureAwait(false)告诉它可以在与原始线程不同的线程上返回控制,从而允许TestAction()完成。

它在控制台应用程序中运行良好,因为他们没有SynchronizationContext坚持将控制权返回给原始线程。 WPF和asp.net具有该自定义同步上下文,因为必须从调用线程进行更改。