No, synchronous calls will not block. For web applications the async methods will free up web server threads to respond to more requests while previous calls are waiting on responses from resource or compute intensive operations.
As a simple example. Lets say I have a web server that is running 100 threads. This means it can handle 100 concurrent requests. Each request takes up to 5 seconds to complete due to handing off to a database to do some reads and updates.
With synchronous calls, if I have 500 active users hitting my web server, the first 100 will take up connection threads while the rest wait their turn for a thread. As operations complete, the next waiting requests will get a thread. Requests can potentially timeout as they wait for a thread to process them.
With asynchronous calls, if I have 500 active users hitting my web server, the first 100 will take up a connection, but as the operations are awaited and running on the database, the web server thread is made available again, starting off handling another request. As operations are completed, an available web server thread can be requested to handle the result and ultimately pass back the response. The web server effectively acts in a more responsive manner for handling more concurrent requests by accepting requests and kicking them off without waiting for the previous ones to complete.
Async does incur a small performance cost in that it needs to be able to resume execution on another thread, or wait on a synchronization context. For operations that can take seconds to run, this is more than worth it, but for methods that can be expected to always complete quickly this is adding a small, but unnecessary performance cost to all calls. As a general rule I default to synchronous calls, then introduce async where I know there will be more than a half second or so processing time. (Significant Database calls like ToList
or complex queries, file I/O, etc.)
When working with ASP.Net Core you also need to be cautious with async code in that it operates without a synchronization context. Code that uses async while referencing non-thread-safe code like a DbContext can have issues where multiple async calls occur without awaiting each in turn.
I.e.
// Should be Ok...
var product = await context.Products.SingleAsync(x => x.ProductId == productId);
var customer = await context.Customers.SingleAsync(x => x.CustomerId == customerId);
var newOrder = new Order { Product = product, Customer = customer};
// Not Ok...
var productGet = context.Products.SingleAsync(x => x.ProductId == productId);
var customerGet = context.Customers.SingleAsync(x => x.CustomerId == customerId);
var newOrder = new Order { Product = await productGet, Customer = await customerGet};
Not the best example, but async operations will execute on a worker thread so the second example would have the two context operations occurring together on different threads.
The first example will run each operation on separate threads, but the 2nd operation will only run once the first has completed. The second will run the operations concurrently.
It's probably not going to manifest a problem unless you are running async operations against the same tables or related tables. I can't be specific on the implications of code like this but it is something to watch out for if you do experience problems working within async methods.