是否正在使用async /等待Web服务的好主意?

时间:2013-06-04 08:32:48

标签: c# web-services concurrency

我有很多Web服务,当他们被调用时,他们需要在返回之前调用其他外部服务来获取信息。这一切都是同步完成的。

因此,如果我有一个返回电影列表的电影GET服务,则Web服务逻辑将等待电影提供商的外部服务返回数据,处理它并返回GET的数据。

通过将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗?处理GET的初始线程是否仍然只是被阻塞等待响应,还是会被释放以处理其他传入的服务调用?

2 个答案:

答案 0 :(得分:5)

  

通过将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗?

包装同步调用可能不会带来太多好处 - 但如果外部服务也提供了真正的异步API,那么您可以获得显着的好处。

  

处理GET的初始线程是否仍然只是被阻塞等待响应,还是会被释放以处理其他传入的服务调用?

我不知道WCF目前对async的支持是什么样的,但它应该可以编写所有这些,以便在实际工作时只有任何线程处于活动状态完成...所以你可以在几个线程上一次处理数百个请求。如果您的任何外部服务调用相对较慢,这一点尤其重要。

所以基本上,获得的收益,但你应该分别考虑两个方面:

  • 您首先要编写的Web服务类型的异步支持。您能否根据WCF中的异步方法表达您的服务?
  • 您将要拨打的外部服务

这些方面中的每一个都可以带来好处,但如果完全支持两个方面,您将获得最大的好处 - 最终得到最简单的代码。

答案 1 :(得分:2)

  

通过将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗?

是的,假设您的API已经异步,例如,您可以轻松地将WebClient更改为HttpClient(或异步使用WebClient),或者您可以wrap Begin/End methods into a Task

想要做的是将同步方法包装到Task.Run中。这将占用一个线程,你将失去可扩展性。

  

处理GET的初始线程是否仍会被阻止等待响应,还是会被释放以处理其他传入的服务调用?

初始线程将被释放以处理其他请求。

  

我有很多网络服务,当他们被调用时,他们需要在返回之前调用其他外部服务获取信息。

这是async / await的理想情况,因为您经常可以同时处理请求:

public async Task<MyResult> GetAsync()
{
  // Start several external requests simultaneously.
  Task<Movie> getMovieTask = GetMovieAsync(...);
  Task<Genre> getGenreTask = GetGenreAsync(...);
  ...

  // Asynchronously wait for them all to complete.
  await Task.WhenAll(getMovieTask, getGenreTask, ...);
  var movie = await getMovieTask;
  var genre = await getGenreTask;
  ...

  // Build the result.
  return ...;
}

在这种情况下,您可以向移动中的外部服务提出多个请求,当您在await Task.WhenAll行中时, no 您的请求正在使用的线程。