具有异步操作的异步控制器不起作用
本文关键字:异步控制 控制器 不起作用 异步 异步操作 | 更新日期: 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 请求运行的所有方法的整体可伸缩性。