简体   繁体   English

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

[英]async Controller with async Action doesn't work

I have async controller with async action. 我有一个具有异步操作的异步控制器。 In the action I call WCF service method in SomeMethodOne (it needs 10 seconds to return result) and then I execute some mathematical operations in SomeMethodTwo (it executes about 6 seconds on my computer). 在该操作中,我在SomeMethodOne中调用WCF服务方法(返回结果需要10秒),然后在SomeMethodTwo中执行一些数学运算(在我的计算机上执行大约6秒)。 As I understand during waiting on result from WCF service method, my computer should execute SomeMethodTwo but it doesn't and all code executes 10 seconds + 6 seconds = 16 seconds. 据我了解,在等待WCF服务方法的结果期间,我的计算机应执行SomeMethodTwo,但不会,并且所有代码都将执行10秒+ 6秒= 16秒。 Why? 为什么?

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

The WCF service which I run locally: 我在本地运行的WCF服务:

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

Your problem is that you're using await right away: 您的问题是您正在立即使用await

string result =  await SomeMethodOne();

The await means that your controller action is going to "asynchronously wait" (await) for the result of SomeMethodOne before it continues executing. await意味着您的控制器操作将在继续执行之前“异步等待”(等待) SomeMethodOne的结果。

If you want to do asynchronous concurrency, then don't await right away. 如果要进行异步并发,请不要立即await Instead, you can start the asynchronous operation going by calling the method and then await later: 相反,您可以通过调用方法来启动异步操作,然后再await

public async Task<ActionResult> Index()
{
  Task<string> firstOperation = SomeMethodOne();

  SomeMethodTwo();

  string result = await firstOperation;

  return View();
}

and then I execute [emphasis mine] 然后我执行[强调我的]

Doing one thing and then doing another thing will take as long as both of them added together. 只要将两者加在一起, 要做一件事然后再做另一件事。

Doing two things at the same time might be quicker. 同时执行两项操作可能会更快。 It might be slower, because of context switching (imagine someone doing lots of "multitasking" and spending more time switching between them than working). 由于上下文切换,它可能会变慢(想象某人做了很多“多任务”,并且在它们之间切换的时间比工作要多)。 It's likely it will be quicker here, if you don't have to get the results from the first action in order to do the second: 如果您不必为了执行第二个操作而从第一个操作中获取结果,那么在这里可能会更快一些:

public async Task<ActionResult> Index()
{
    Task<string> task =  SomeMethodOne();

    SomeMethodTwo();

    string result = await task;

    return View();
}

Obviously if you needed result before you could call SomeMethodTwo() then this wouldn't be possible. 显然,如果在调用SomeMethodTwo()之前需要result ,那么将不可能。 There is still an advantage on await ing SomeMethodOne() (which should be called SomeMethodOneAsync() if possible to fit with .NET conventions), in that if GetDataAsync() is truly async then the thread that was executing this action method can do something else for some other request to your web application, and another thread will pick up on dealing with this one when the I/O operation has returned data. await SomeMethodOne() (如果可能与.NET约定相适应,则应称为SomeMethodOneAsync()仍然有一个优势,即如果GetDataAsync()是真正异步的,则执行此操作方法的线程可以执行某些操作否则将向Web应用程序发出其他请求,并且当I / O操作返回数据时,另一个线程将继续处理该请求。 This doesn't help the performance of the single method involved, but does help overall scalability of all the methods being run on the machine for all the web requests. 这不利于所涉及的单个方法的性能,但确实有助于针对所有Web请求在计算机上运行的所有方法的整体可伸缩性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM