Using the async keyword in a method signature to return a task to a Web Api endpoint

If I wanted to write a non-blocking web api action returning a Task object, I could do this with or without using the async as such:

Using async

 public async Task<HttpResponseMessage> Get() { Func<HttpResponseMessage> slowCall = () => { Thread.Sleep(2000); return Request.CreateResponse(HttpStatusCode.OK, "Hello world"); }; var task = Task<HttpResponseMessage>.Factory.StartNew(slowCall); return await task; } 

Without using async

 public Task<HttpResponseMessage> Get() { Func<HttpResponseMessage> slowCall = () => { Thread.Sleep(2000); return Request.CreateResponse(HttpStatusCode.OK, "Hello world"); }; var task = Task<HttpResponseMessage>.Factory.StartNew(slowCall); return task; } 

Both of them work fine. However, every example I have seen (online and in books) when writing a web api action that returns Task uses the async . Of course, I understand that this gives you more flexibility, as it allows you to control what you want to β€œwait” and what not. But provided that your functionality can be handled efficiently anyway,

  • Is there any advantage to using one approach and another?
  • Should I always use the async keyword (and if so, why)?
  • Or does it not matter?
+6
source share
2 answers

The async allows you to use await in your method by creating a state machine. If you can control the return of an asynchronous task without using it, you can continue and delete it, since it has some (very small) overhead. Keep in mind that this is only useful in a few cases. Your return await is one of them.

Another difference is how exceptions are handled. If there is an exception in the synchronous part of the method and it is marked as async , the exception will be saved in the returned task. Without a keyword, an exception will be thrown regularly. For example, in this case there is a big difference:

 var task = Get(); // unhandled exception without async try { var result = await task; // handled exception with async } catch { } 

My recommendation is to use the async , even if you absolutely do not need *, because most developers do not understand the difference, and the value in optimization is mostly insignificant.


* If you and your teammates do not know what you are doing.

+4
source

There is one advantage of bypassing await and directly returning Task : performance. You will not allocate or process the state machine that goes with the async method. However, there are some minor differences when using exceptions.

In the asynchronous example, any thrown exceptions will be enclosed in Task . This usually means that people assume that this will happen when they call a method that returns a task. In the synchronization example, exceptions will be thrown immediately after the call.

This will also affect the exception stack trace. In the async example, it will show Get() . In the sync example, it will show your anonymous delegate or, even worse, some internal crap in Task.Factory.StartNew without actually linking to your actual code. This can lead to debugging a little more complicated.

+1
source

Source: https://habr.com/ru/post/976277/


All Articles