异步 MVC 控制器操作方法执行未在“等待”处等待

本文关键字:等待 MVC 控制器 操作方法 执行 异步 | 更新日期: 2023-09-27 17:56:18

我正在使用MVC 4和.NET 4.5。我希望利用新的TAP(异步等待)构建一个异步控制器。我从Controller而不是AsyncContoller继承了这个控制器,因为我使用的是基于任务的异步性,而不是基于事件的异步性。

我有两种操作方法 - 一种用于同步执行操作,另一种用于异步执行相同的操作。我的视图中的表单中还有两个提交按钮,每个操作方法一个。

以下是这两种方法的代码:

同步:

[HttpPost]
public ActionResult IndexSync(FormCollection formValues)
{
        int Min = Int32.Parse(formValues["txtMin"]);
        int Count = Int32.Parse(formValues["txtCount"]);
        string Primes;
        DateTime started = DateTime.Now;
        using (BackendServiceReference.ServiceClient service = new ServiceClient())
        {
            Primes = service.GetPrimesServiceMethod(Min, Count);
        }
        DateTime ended = DateTime.Now;
        TimeSpan serviceTime = ended - started;
        ViewBag.ServiceTime = serviceTime;
        ViewBag.Primes = Primes;
        return View("Index");
}

异步:

[HttpPost]
public async Task<ActionResult> IndexAsync(FormCollection formValues)
{
        int Min = Int32.Parse(formValues["txtMin"]);
        int Count = Int32.Parse(formValues["txtCount"]);
        string Primes;
        Task<string> PrimesTask;
        DateTime started = DateTime.Now;
        using (BackendServiceReference.ServiceClient service = new ServiceClient())
        {
            PrimesTask = service.GetPrimesServiceMethodAsync(Min, Count);
        }
        DateTime ended = DateTime.Now;
        TimeSpan serviceTime = ended - started;
        ViewBag.ServiceTime = serviceTime;
        Primes = await PrimesTask;
        ViewBag.Primes = Primes;
        return View("Index");
}

在异步方法中,我希望DateTime ended = DateTime.Now在调用服务方法后立即执行,而耗时的服务方法在后台异步执行。

但是,这不会发生,并且在调用服务方法时执行"等待",而不是在发生Primes = await PrimesTask的地方等待。

我错过了什么吗?

如果能朝着正确的方向推动一下,我们将不胜感激。

异步 MVC 控制器操作方法执行未在“等待”处等待

我怀疑它实际上是在ServiceClient.Dispose中阻塞。

要解决此问题,请扩展using块以包含您的await

using (BackendServiceReference.ServiceClient service = new ServiceClient())
{
    PrimesTask = service.GetPrimesServiceMethodAsync(Min, Count);
    DateTime ended = DateTime.Now;
    TimeSpan serviceTime = ended - started;
    ViewBag.ServiceTime = serviceTime;
    Primes = await PrimesTask;
}
ViewBag.Primes = Primes;