繁体   English   中英

当控制器操作同步时,有什么理由使用async / await吗?

[英]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.

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