command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

CommandHandler.GetExitCodeAsync only awaits Task<int> return types

Open williamb1024 opened this issue 2 years ago • 1 comments

I believe it would make sense that GetExitCodeAsync: https://github.com/dotnet/command-line-api/blob/a0782c85fd8f7aed16f46935998e9280c86ed2fb/src/System.CommandLine.NamingConventionBinder/CommandHandler.cs#L607

Should await any return object that is a descendant of the Task type. If the type is Task<int> the int value should be returned, otherwise, return 0.

As it stands, an asynchronous method used as a command handler that does not return an int is unlikely to run to completion if the System.CommandLine.Hosting code is used.

This can be seen easily in:

https://github.com/dotnet/command-line-api/blob/a0782c85fd8f7aed16f46935998e9280c86ed2fb/samples/HostingPlayground/Program.cs#L36

by adding an await Task.Delay(TimeSpan.FromSeconds(10)); to force the Run method to yield.

williamb1024 avatar Dec 21 '23 08:12 williamb1024

Overall I don't like checking whether the dynamic type of the return value is Task or Task<int>. This can break if a handler is declared to return Task but is not async and gets the Task from code that returns a Task<int> as an implementation detail. I'd rather see ModelBindingCommandHandler check the static return type of _handlerMethodInfo or _handlerDelegate.

KalleOlaviNiemitalo avatar Dec 21 '23 09:12 KalleOlaviNiemitalo