Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do using statements and await keywords play nicely in c#

I have a situation where I am making an async call to a method that returns and IDisposable instance. For example:

HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")); 

Now before async was on the scene, when working with an IDisposable instance, this call and code that used the "response" variable would be wrapped in a using statement.

My question is whether that is still the correct approach when the async keyword is thrown in the mix? Even though the code compiles, will the using statement still work as expected in both the examples below?

Example 1

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com"))) {     // Do something with the response      return true; } 

Example 2

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com"))) {     await this.responseLogger.LogResponseAsync(response);      return true; } 
like image 296
swingdoctor Avatar asked May 15 '13 13:05

swingdoctor


People also ask

What is the purpose of await keyword?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.

What is one benefit of using async await?

The biggest advantage of using async and await is, it is very simple and the asynchronous method looks very similar to a normal synchronous methods. It does not change programming structure like the old models (APM and EAP) and the resultant asynchronous method look similar to synchronous methods.

What is the purpose of async await keywords?

The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. await can only be used inside an async method.

What happens when await is called?

await releases the current thread, but NOT to the thread pool. The UI thread doesn't come from the thread pool. If you run asynchronous method, e.g. ExecuteScalarAsync without async, await keywords, then this method will run asynchronously no matter what. The calling thread won't be affected .


1 Answers

Yes, that should be fine.

In the first case, you're really saying:

  • Asynchronously wait until we can get the response
  • Use it and dispose of it immediately

In the second case, you're saying:

  • Asynchronously wait until we can get the response
  • Asynchronously wait until we've logged the response
  • Dispose of the response

A using statement in an async method is "odd" in that the Dispose call may execute in a different thread to the one which acquired the resource (depending on synchronization context etc) but it will still happen... assuming the thing you're waiting for ever shows up or fail, of course. (Just like you won't end up calling Dispose in non-async code if your using statement contains a call to a method which never returns.)

like image 117
Jon Skeet Avatar answered Sep 29 '22 18:09

Jon Skeet