How do I make my repositories async without affecting upper layers
asp.net-mvc-5, async-await
Solution
As with 99% of applications everything can and should be executed synchronously except calls into database.
Not at all. Anything that is I/O-based should be asynchronous.
So, the data layer does database I/O, and should be asynchronous.
The business logic layer uses the data layer, which is I/O-based, and should be asynchronous.
The UI layer uses the business logic layer, which is I/O-based, and should be asynchronous.
Of course, only those methods that are actually I/O-based should be made asynchronous; the rest should be synchronous. But I find that in data-access-heavy applications, they should be almost entirely asynchronous.
Does this make sense and would I actually get my code to execute in asynchronous manner?
No. Sorry, but you should never wrap asynchronous code in `Task.Run` and block on it in an ASP.NET application. All that does is use up more threads than necessary for processing your request. It would be better to keep it all synchronous than to use multiple threads to keep it synchronous.
On ASP.NET, you have to allow the asynchrony to propagate through all layers in order to have asynchronous actions/handlers (and all the benefits that come with it, namely, scalability).
Problem
I have an Asp.net MVC 5 application that has: - Web UI layer - Business Logic layer - Data repositories layer They are also referenced in this order. UI only accesses business logic, and business logic references repositories. As with 99% of applications everything can and should be executed synchronously except calls into database (or other I/O expensive operations). That's why I would like to make Data layer asynchronous but without affecting upper layers to make all upper calling methods async (all the way to controller actions). Is that possible? What I was thinking to do I was thinking of changing things this way. Data layer method ``` public async Task<SomeEntity> GetData() { return await Task.Run<SomeEntity>(() => ...); } ``` Business logic method ``` public SomeEntity GetData() { return this.repo.GetData().Result; } ``` Questions Does this make sense and would I actually get my code to execute in asynchronous manner? Update After reading Stephen Cleary's blog post it made it more clear to me that whole call stack to the bottom (data layer that splits the synchronisity) is being split by the data async call hence all calls on the stack should be async and split as well. If this thinking is correct then are my assumptions correct when I say that In order to not have the whole synchronous call stack converted to async we should create a separate thread that would work asynchronously and our synchronous thread would use it. Question 2 Is this assumption correct and if it is, is that the only way to keep some parts synchronous?