AspNetCoreDiagnosticScenarios icon indicating copy to clipboard operation
AspNetCoreDiagnosticScenarios copied to clipboard

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

Open sleemer opened this issue 5 years ago • 9 comments

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:

  • to get access to DI container in async initializer
  • to run initialization logic (bootstrapping) before executing the Host itself

sleemer avatar Jan 11 '19 09:01 sleemer

Just write an IHostedService and write the async logic in StartAsync

davidfowl avatar Jan 15 '19 06:01 davidfowl

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...

sleemer avatar Jan 15 '19 10:01 sleemer

.Wait() in Startup.Configure()?

tibitoth avatar Jan 15 '19 14:01 tibitoth

@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)

sleemer avatar Jan 16 '19 08:01 sleemer

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/

slang25 avatar Jan 16 '19 09:01 slang25

@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...

sleemer avatar Jan 16 '19 09:01 sleemer

That would be nice to have this asynchronous startup filter !

jonathanantoine avatar Oct 07 '20 20:10 jonathanantoine

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

jack4it avatar Nov 12 '21 22:11 jack4it

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

davidfowl avatar Nov 12 '21 22:11 davidfowl