-1

When I create a new service fabric application with a stateless aps.net core service, why is this line of code in the main method of the service?

// prevents this host process from terminating so services keep running
Thread.Sleep(Timeout.Infinite)

Obviously as the code comment above the actual code says, this is to prevent the host process from terminating. But why not make the main method return an async Task instead of void to be able to use await Task.Delay()? From my understanding the latter would be better because the main thread would be put back into the thread pool to actually do something useful and not just sit there doing nothing other than waiting.

The code a couple of lines above leads me to believe that this is just a leftover from when the main method could not return an async Task.

ServiceRuntime.RegisterServiceAsync("FirstStatelessApiType",
    context => new FirstStatelessApi(context)).GetAwaiter().GetResult();

(GetAwaiter().GetResult() would also be unnccessary if the method would just return an async Task as it could then be awaited)

Edit: I have already tested switching from void Mainto async Task Main and using await Task.Delay(Timeout.Infinite) instead of Thread.Sleep and did not see a difference in the behavior of my service (api endpoints were still running and working as expected)

Lucas
  • 26
  • 3
  • 1
    Try it out and find out. The rule is that a process will terminate when there are no `Foreground` threads still running. Create a simple Console app that creates a thread. Mark it foreground add the delay and start it. The console app will start, start the other thread and return. But the process won't terminate, the other thread, now stopped will keep it alive. Now try it with `Task.Delay` and see what happens – Flydog57 Feb 25 '23 at 22:30
  • Thanks for the information, I did not know that a process will terminate once all `Foreground` threads have finished. But from my understandig it is enough to test this with a console that does nothing but `await Task.Delay()`at the end (so technically the same as in the serice fabric service). This works perfectly fine. And I forgot to mention in the question, that I already tested this in the service fabric api and could not see a difference. – Lucas Feb 25 '23 at 23:06
  • 1
    [Don't post code as an image, please.](//meta.stackoverflow.com/q/285551) Code is meant to be posted as text and marked down as code. – Wyck Feb 25 '23 at 23:12
  • Alright thanks for the advice. I updated the question, sorry. – Lucas Feb 25 '23 at 23:32

1 Answers1

2

But why not make the main method return an async Task instead of void to be able to use await Task.Delay()? From my understanding the latter would be better because the main thread would be put back into the thread pool to actually do something useful and not just sit there doing nothing other than waiting.

That's not actually what happens when async Task Main is used. What actually happens is that the main thread is (synchronously) blocked on the Task returned from Main; this is to prevent the process from exiting.

The code a couple of lines above leads me to believe that this is just a leftover from when the main method could not return an async Task.

This is a good point, and I would use async Task Main and use await instead of blocking anywhere. The code would essentially behave the same, but it would look more correct.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810