任务完成后,ASP.NET MVC应用程序无响应

时间:2017-12-21 04:28:56

标签: asp.net async-await task-parallel-library

我有一个在.NET Framework 4.7.1上运行的ASP.NET MVC 5 Web应用程序。

在控制器的操作中,我们调用服务的方法,有时会启动一个新的Task,如下所示:

控制器:

public async Task<ActionResult> Index()
{
    Info info = await this.someService.GetInformationAsync().ConfigureAwait(false);
    return this.ProcessInfo( info );
}

SomeService(在static中作为Global.asax对象存在):

private readonly Object taskLock = new Object();
private Task errorCheckerTask;

public Task<Info> GetInformationAsync()
{
    try
    {
        ...
    }
    catch( Exception ex )
    {
        this.StartErrorChecker();
    }

    return null;
}

private void StartErrorChecker()
{
    lock( this.taskLock )
    {
        if( this.errorCheckerTask == null || this.errorCheckerTask.Status >= TaskStatus.RanToCompletion )
        {
            this.errorCheckerTask = this.BeginErrorCheckerAsync( CancellationToken.None );
        }
    } 
}

private async Task BeginErrorCheckerAsync( CancellationToken ct )
{
    while( !ct.IsCancellationRequested )
    {
        Boolean ok = await DoStuff();
        if( ok ) return;
        await Task.Delay( 30 * 1000 ).ConfigureAwait(false);
    }
}

第一次启动BeginErrorCheckerAsync任务后,情况似乎没问题 - 但是当BeginErrorCheckerAsync第二次运行时,Visual Studio的Output窗口会报告一堆线程结束然后网络应用程序停止响应任何新的HTTP请求 - 所有浏览器只是说他们在发送请求后正在等待响应。

我按下了Break按钮,Visual Studio Threads窗口只显示了一些运行的线程,其中没有一个线程在任何堆栈跟踪中都有任何用户代码。

重要的是,除了有关线程的消息之外,没有引发第一次机会异常或在“输出”窗口中显示任何异常输出:

  

线程0x5440已退出,代码为0(0x0)。   线程0x547c已退出,代码为0(0x0)。   线程0x5450已退出,代码为0(0x0)。   线程0x5474已退出,代码为0(0x0)。

我假设我没有在ASP.NET MVC中发现错误 - 但我不明白我对Tasks / async / await的使用如何使ASP.NET陷入僵局(假设这是问题)。我注意到我的代码中没有任何地方可以调用task.Resulttask.Wait()来排除传统形式的async / await死锁,而且无论如何都没有.NET代码中的线程堆栈跟踪。

1 个答案:

答案 0 :(得分:0)

您无法在控制器操作方法上调用ConfigureAwait(false),因为它们必须在同步上下文中运行。