[英]Any reason to use async/await when the controller action is sync?
让我说我有一个控制器动作不能异步(由于各种原因),但我有一个服务(通过几种方法)使用HttpClient
调用休息服务。 使用异步客户端并使用.Wait
或.Result
有什么好处吗? 或者使用同步方法的性能会降低吗?
所以要么:
//MyController.cs
public ActionResult GetSomething(int id)
{
//lots of stuff here
var processedResponse = _myService.Get(id);
//lots more stuff here
return new ContentResult(result);
}
//MyService.cs
public ProcessedResponse Get(int id)
{
var client = new HttpClient();
var result = client.Get(_url+id);
return Process(result);
}
要么:
//MyController.cs
public ActionResult GetSomething(int id)
{
//lots of stuff here
var processedResponse = _myService.GetAsync(id).Result;
//or, .Wait, or Task.Run(...), or something similar
//lots more stuff here
return new ContentResult(result);
}
//MyService.cs
public async Task<ProcessedResponse> GetAsync(int id)
{
var client = new HttpClient();
var result = await client.GetAsync(_url+id);
return await Process(result);
}
通过使用异步客户端并将方法包装在Task.Run(()=> _myService.Get())中是否有任何好处。结果?
你最有可能获得的唯一一件事就是僵局 。 想想看,你在线程池线程上排队一个自然异步的方法,ASP.NET已经给你一个线程来处理你里面的Action。 那没有多大意义。
如果你想异步,并认为你实际上会从异步提供的规模中受益 ,那么你应该将你的控制器重新分配为异步并返回一个Task<T>
,你可以await
那里await
那些异步方法。
所以我要么保持同步,要么将代码从上到下重新分解以支持异步:
//MyController.cs
public async Task<ActionResult> GetSomethingAsync(int id)
{
//lots of stuff here
await GetAsync(id);
return new ContentResult(result);
}
//MyService.cs
public async Task<ProcessedResponse> GetAsync(int id)
{
var client = new HttpClient();
var result = await client.GetAsync(_url+id);
return await Process(result);
}
在您的方案中,没有一个很好的理由,但我们添加一些功能:
//MyController.cs
public ActionResult GetSomething(int id)
{
//lots of stuff here
var processedResponse = _myService.GetAsync(id).Result;
//or, .Wait, or Task.Run(...), or something similar
//lots more stuff here
return new ContentResult(result);
}
//MyService.cs
public async Task<ProcessedResponse> GetAsync(int id)
{
var client = new HttpClient();
var pendingResult1 = client.GetAsync(_url+id);
var pendingResult2 = someAsyncOperation();
var result3 = someSyncOperation();
var result1 = await pendingResult;
var result2 = await pendingResult2;
return await Process(result1, result2, result3);
}
现在,由于您的请求需要一段时间才能完成,因此someAsynchOperation
立即开始执行,而不是等待GetAsync()
完成。 someSyncOperation
也在此期间执行。
如果没有async
关键字,您将无法使用await
,因此如果您计划在函数内部进行异步执行,最好使用它。
如果可以这样做的话会很有趣
//MyController.cs
public ActionResult GetSomething(int id)
{
var processedResponseTask = _myService.GetAsyn(id)
//lots of stuff here (1)
var processedResponseTask.Wait();
var processedResponse = processedResponseTask.Result;
//lots more stuff here (2)
return new ContentResult(result);
}
现在这里的很多东西(1)与你的异步任务并行完成。 (或者,例如,如果您两次调用您的服务)。 如果你实际上并没有在这里做很多事情(1),那么没有太多意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.