davidfowl / AspNetCoreDiagnosticScenarios

This repository has examples of broken patterns in ASP.NET Core applications
7.69k stars 740 forks source link

Async application initialization in asp.net core and .net core apps #40

Open sleemer opened 5 years ago

sleemer commented 5 years ago

Hi, what's currently the recommended way to run async application initialization in asp.net core and .net core apps based on IGenericHost? Wouldn't it be a nice idea to integrate async initialization into WebHost and GenericHost themselves? As an example we could use https://github.com/thomaslevesque/AspNetCore.AsyncInitialization/ What I am trying to achieve with that is:

davidfowl commented 5 years ago

Just write an IHostedService and write the async logic in StartAsync

sleemer commented 5 years ago

But, what if it need to be done before running any other application code? Some initialization (e.g. loading some data from a disc and creating an index in memory), similar to what is exposed through IStartupFilter. Because what we can achive using IHostedService is to run some async code in parallel...

tibitoth commented 5 years ago

.Wait() in Startup.Configure()?

sleemer commented 5 years ago

@totht91 It's never a good idea to call .Wait on the Task and @davidfowl did a great job explaining why (look for more details here https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#avoid-using-taskresult-and-taskwait)

slang25 commented 5 years ago

In fairness, the general good guidance of not calling .Wait may not apply here if the code is being called by the entrypoint thread. You can't yield the entrypoint thread back to the theadpool for example, if Main is async, then under the hood it will be calling .GetAwaiter().GetResult() effectively doing the blocking for you.

I see this as about not having to comment in the code having to explain why it's ok here, it's far easier to outright ban .Wait() regardless of if it is problematic or not.

Switching topics, here's some other info on async initialization that outlines a different approach (in addition to the same solution Thomas Levesque proposes): https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-1/ https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-part-2/

sleemer commented 5 years ago

@slang25 thanks! I've read these articles, they are really interesting, but unfortunately they only work for asp.net core apps, and what I'm looking for is a more general approach, that can be applied for both asp.net core (WebHost) and .net core app (GenericHost). The problem with RunWithTasksAsync is that you loose the ability to host your app in WindowsService without introducing wrappers around existing RunAsync and RunAsService extension methods, but at least it could be done, and probably that's the way to go for now. The second approach works only for asp.net core apps, becouse there are obviously no IServer in GenericHost scenario. What I was thinking is more like having an async version of IStartupFilter...

jonathanantoine commented 3 years ago

That would be nice to have this asynchronous startup filter !

jack4it commented 2 years ago

r we having sth for this in .net 6? @davidfowl or maybe in .net 7? :)

davidfowl commented 2 years ago

In .NET 6, you can just write async code in the top level statement 😄