在Task.Run()中包装同步调用以使其异步有益吗?

时间:2012-10-25 15:19:02

标签: .net async-await asp.net-web-api

我对这个问题的动机是因为我正在创建一个.net web API项目,该项目将使用具有同步方法的现有neo4j rest api客户端。我想通过转向异步方法来利用一些性能提升,但我想避免进入neo4j api库并重构同步方法以返回异步方法。我想知道是否在await Task.Run()中包含对同步方法的调用将是有益的。具体来说,当第一个例子中,来自httpClient的异步结果调用Wait()方法时会发生什么,但是整个事情都包含在另一个等待中。

还要记住,我会在AppHarbor云上运行它,我相信它是一个虚拟核心。

以下是

  //what happens with the synchronous rest api client I am using
  HttpResponseMessage SendHttpRequest(HttpRequestMessage request)
  {

        var requestTask = httpClient.SendAsync(request);
        requestTask.Wait();
        return requestTask.Result;

  }

  object result = await Task.Run(() =>
  {
      return SendHttpRequest(request);
  });

性能与

相似
 return httpClient.SendAsync(request)

2 个答案:

答案 0 :(得分:8)

  

我想通过转向异步方法来利用一些性能提升,但我想避免进入neo4j api库并重构同步方法以返回异步方法。

抱歉,如果您只是在async中包装同步代码,则会失去服务器端Task.Run的所有好处。

async在服务器上很好,因为异步操作比线程更好。但是,如果您使用Task.Run,那么无论如何您都在使用线程。

答案 1 :(得分:2)

不同之处在于Task.Run方法只是在线程池上运行相同的阻塞代码。这意味着虽然它不会阻塞你的调用线程,但它会阻塞执行线程。

重要的是完全取决于资源和性能方面的考虑。

如果SendHttpRequest方法真的只是等待httpClient.SendAsync任务,你可以简单地避免使用该方法并写下:

object result = await httpClient.SendAsync(request);

或者:

object result = await Task.Run(async () => await httpClient.SendAsync(request));

如果仍然应该在单独的线程上运行SendAsync任务。