简体   繁体   English

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

[英]Is using aync/await a good idea for web services?

I have many web services which when they are called they need to call other external services for information before returning. 我有很多Web服务,当它们被调用时,它们需要在返回之前调用其他外部服务来获取信息。 This is all done synchronously. 这一切都是同步完成的。

So if I have a movie GET service that returns a list of movies, the web service logic will wait for the movie provider's external service to return the data, process it and return the data for the GET. 因此,如果我有一个返回电影列表的电影GET服务,Web服务逻辑将等待电影提供商的外部服务返回数据,处理它并返回GET的数据。

Would it prove to be any benefit by wrapping the external service call in a Task and use the async/await model? 将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗? Wouldn't the initial thread handling the GET still just be blocked waiting for the response or would it be freed up to handle other incoming service calls? 处理GET的初始线程是否仍然只是被阻塞等待响应,还是会被释放来处理其他传入的服务调用?

Would it prove to be any benefit by wrapping the external service call in a Task and use the async/await model? 将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗?

Wrapping synchronous calls probably wouldn't provide much benefit - but if the external service provides a genuine async API as well, you could get a significant benefit. 包装同步调用可能不会带来太多好处 - 但如果外部服务提供真正的异步API,您可以获得显着的好处。

Wouldn't the initial thread handling the GET still just be blocked waiting for the response or would it be freed up to handle other incoming service calls? 处理GET的初始线程是否仍然只是被阻塞等待响应,还是会被释放来处理其他传入的服务调用?

I don't know what WCF's support for async is like at the moment, but it should be possible to write all of this so that you only have any threads active when there's actual work to be done... so you could be handling hundreds of requests at a time on just a couple of threads. 我不知道WCF目前对async的支持是什么样的,但是应该可以编写所有这些内容,以便在实际工作完成时只有任何线程处于活动状态...所以你可以处理数百个只有几个线程的请求。 This is particularly important if any of your external service calls are relatively slow. 如果您的任何外部服务调用相对较慢,这一点尤为重要。

So basically, there are gains to be made, but you should look into two aspects separately: 所以基本上, 要取得收益,但你应该考虑两个方面分开:

  • The async support for the type of web service you're writing in the first place. 首先是您正在编写的Web服务类型的异步支持。 Can you express your service in terms of async methods within WCF? 你能否在WCF中用异步方法表达你的服务?
  • The external service you'll be calling 您将要拨打的外部服务

Each of those aspects can provide benefit, but you'll get the biggest benefit - and end up with the simplest code - if both aspects are fully supported. 这些方面中的每一个都可以带来好处,但如果两个方面都得到完全支持,您将获得最大的好处 - 最终得到最简单的代码。

Would it prove to be any benefit by wrapping the external service call in a Task and use the async/await model? 将外部服务调用包装在Task中并使用async / await模型可以证明它有什么好处吗?

Yes, assuming that your API is already asynchronous, eg, you can easily change WebClient to HttpClient (or use WebClient asynchronously), or you can wrap Begin / End methods into a Task . 是的,假设您的API已经异步,例如,您可以轻松地将WebClient更改为HttpClient (或异步使用WebClient ),或者您可以Begin / End方法包装到Task

What you don't want to do is wrap a synchronous method into Task.Run . 什么你不想做的就是换一个同步方法到Task.Run That will use up a thread and you will lose your scalability. 这将耗尽一个线程,你将失去你的可扩展性。

Wouldn't the initial thread handling the GET still just be blocked waiting for the response or would it be freed up to handle other incoming service calls? 处理GET的初始线程是否仍然只是被阻塞等待响应,还是会被释放来处理其他传入的服务调用?

The initial thread would be freed up to handle other requests. 初始线程将被释放以处理其他请求。

I have many web services which when they are called they need to call other external services for information before returning. 我有很多Web服务,当它们被调用时,它们需要在返回之前调用其他外部服务来获取信息。

This is an ideal situation for async / await because you can often do requests concurrently: 这是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 ...;
}

In this case, you can have multiple requests to external services in flight, and while you're in the await Task.WhenAll line, there are no threads being used by your request. 在这种情况下,您可以在飞行中对外部服务发出多个请求,当您处于await Task.WhenAll行时,您的请求不会使用任何线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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