简体   繁体   中英

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. 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.

Would it prove to be any benefit by wrapping the external service call in a Task and use the async/await model? 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?

Would it prove to be any benefit by wrapping the external service call in a Task and use the async/await model?

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.

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?

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. 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. Can you express your service in terms of async methods within 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?

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 .

What you don't want to do is wrap a synchronous method into 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?

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.

This is an ideal situation for async / await because you can often do requests concurrently:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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