我有异步操作的异步控制器。在动作中我在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);
}
}
答案 0 :(得分:3)
您的问题是您现在正在使用await
:
string result = await SomeMethodOne();
await
表示您的控制器操作将以异步方式等待&#34; (等待)SomeMethodOne
在继续执行之前的结果。
如果您想进行异步并发,请立即不要await
。相反,您可以通过调用方法然后await
稍后启动异步操作:
public async Task<ActionResult> Index()
{
Task<string> firstOperation = SomeMethodOne();
SomeMethodTwo();
string result = await firstOperation;
return View();
}
答案 1 :(得分:1)
和然后我执行[强调我的]
做一件事,然后做另一件事,只要他们两个都加在一起。
同时做两件事可能更快。它可能会更慢,因为上下文切换(想象有人做了很多“多任务”并花费更多时间在他们之间切换而不是工作)。如果您不必从第一个动作中获得结果来执行第二个操作,那么这里可能会更快:
public async Task<ActionResult> Index()
{
Task<string> task = SomeMethodOne();
SomeMethodTwo();
string result = await task;
return View();
}
显然,如果您在致电result
之前需要SomeMethodTwo()
,那么这是不可能的。 await
SomeMethodOne()
仍然有一个优势(如果可能的话,应该被称为SomeMethodOneAsync()
以适应.NET约定),如果GetDataAsync()
真的是异步,那么正在执行此操作方法的线程可以对Web应用程序的某些其他请求执行其他操作,而另一个线程将在I / O操作返回数据时处理此操作。这对所涉及的单个方法的性能没有帮助,但确实有助于在机器上为所有Web请求运行的所有方法的整体可伸缩性。