具有异步操作的异步控制器不起作用

本文关键字:异步控制 控制器 不起作用 异步 异步操作 | 更新日期: 2023-09-27 18:33:55

我有带有异步操作的异步控制器。在操作中,我在 SomeMethodOne 中调用 WCF 服务方法(它需要 10 秒才能返回结果(,然后在 SomeMethodTwo 中执行一些数学运算(它在我的计算机上执行大约 6 秒(。正如我在等待WCF服务方法的结果期间所了解的那样,我的计算机应该执行SomeMethodTwo,但它没有执行,并且所有代码执行10秒+ 6秒= 16秒。为什么?

public class TestController : AsyncController
{
    public async Task<ActionResult> Index()
    {
        string result =  await SomeMethodOne();
        SomeMethodTwo();
        return View();
    }
    private async Task<string> SomeMethodOne() // it needs 10 seconds to return result from WCF service
    {
        using (Service1Client client = new Service1Client())
        {
            return await client.GetDataAsync(5);
        }
    }
    private void SomeMethodTwo() // it executes about 6 seconds on my computer
    {
        double result = 0;
        for (int i = 0; i < 1000000000; i++)
        {
            result += Math.Sqrt(i);
        }
    }
}

我在本地运行的 WCF 服务:

public class Service1 : IService1
{
    public string GetData(int value)
    {
        Thread.Sleep(10000);
        return string.Format("You entered: {0}", value);
    }        
}

具有异步操作的异步控制器不起作用

您的问题是您立即使用await

string result =  await SomeMethodOne();

await意味着您的控制器操作将在继续执行之前"异步等待"(await(SomeMethodOne的结果。

如果要执行异步并发,请不要立即await。相反,您可以通过调用该方法启动异步操作,然后稍后await

public async Task<ActionResult> Index()
{
  Task<string> firstOperation = SomeMethodOne();
  SomeMethodTwo();
  string result = await firstOperation;
  return View();
}

然后我执行[强调我的]

一件事然后做另一件事需要很长时间,只要两者加在一起。

同时做两件事可能会更快。由于上下文切换,它可能会更慢(想象一下,有人做了很多"多任务处理",并且花更多的时间在它们之间切换而不是工作(。如果您不必从第一个操作中获取结果来执行第二个操作,那么这里可能会更快:

public async Task<ActionResult> Index()
{
    Task<string> task =  SomeMethodOne();
    SomeMethodTwo();
    string result = await task;
    return View();
}

显然,如果您在打电话之前需要result SomeMethodTwo()那么这是不可能的。await ing SomeMethodOne()(如果可能的话,应SomeMethodOneAsync()调用以符合 .NET 约定(仍然有一个优势,因为如果GetDataAsync()确实是异步的,那么执行此操作方法的线程可以对 Web 应用程序的其他一些请求执行其他操作,并且当 I/O 操作返回数据时,另一个线程将开始处理此线程。这无助于所涉及的单个方法的性能,但确实有助于计算机上针对所有 Web 请求运行的所有方法的整体可伸缩性。