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

时间:2015-11-25 10:16:07

标签: c# asp.net asynchronous async-await

假设我有一个控制器操作无法异步(由于各种原因),但我有一个服务(通过几种方法)使用bool sortRecord(const Record& left, const Record& right) { return left.getArrival().getDate() < right.getArrival().getDate(); } 调用休息服务。使用异步客户端并使用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);
}

3 个答案:

答案 0 :(得分:5)

  

使用异步客户端并包装它是否有任何好处   Task.Run(()=&gt; _myService.Get())中的方法。结果?

你最有可能最终获得的是死锁。想想看,你在线程池线程上排队一个自然异步的方法,ASP.NET已经给你一个线程来处理你里面的Action。没有多大意义。

如果你想异步,并且认为你实际上从异步提供的规模中受益,那么你应该将你的控制器重新分配为异步并返回{{1你可以Task<T>那些异步方法。

所以我要保持同步,要么将代码从上到下重新分配以支持异步:

await

答案 1 :(得分:2)

在您的方案中,没有一个很好的理由,但我们可以添加一些功能:

//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,因此如果您打算在函数内部进行异步执行,最好使用它。

答案 2 :(得分:0)

如果可以这样做,那就很有趣了

//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),那么就没有太多意义了。