diff --git a/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt b/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt index cfac3fae65..cd832ed67a 100644 --- a/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt +++ b/src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt @@ -55,6 +55,7 @@ public System.Void SetAction(System.Func action) public System.Void SetAction(System.Func action) public System.Void SetAction(System.Func action) + public System.Void SetAction(System.Func> action) public System.Void SetAction(System.Func> action) public static class CompletionSourceExtensions public static System.Void Add(this System.Collections.Generic.List>> completionSources, System.Func> completionsDelegate) diff --git a/src/System.CommandLine.Tests/Invocation/InvocationTests.cs b/src/System.CommandLine.Tests/Invocation/InvocationTests.cs index 0de312a178..745ccaed1f 100644 --- a/src/System.CommandLine.Tests/Invocation/InvocationTests.cs +++ b/src/System.CommandLine.Tests/Invocation/InvocationTests.cs @@ -160,6 +160,16 @@ public async Task Anonymous_RootCommand_Task_returning_Action_can_set_custom_res (await rootCommand.Parse("").InvokeAsync()).Should().Be(123); } + [Fact] + public async Task Anonymous_RootCommand_Task_int_returning_Action_can_set_custom_result_code_via_InvokeAsync() + { + var rootCommand = new RootCommand(); + + rootCommand.SetAction(_ => Task.FromResult(123)); + + (await rootCommand.Parse("").InvokeAsync()).Should().Be(123); + } + [Fact] public void Anonymous_RootCommand_int_returning_Action_can_set_custom_result_code_via_Invoke() { diff --git a/src/System.CommandLine/Command.cs b/src/System.CommandLine/Command.cs index 44e60aa1e8..be565651d2 100644 --- a/src/System.CommandLine/Command.cs +++ b/src/System.CommandLine/Command.cs @@ -166,13 +166,36 @@ public void SetAction(Func action) throw new ArgumentNullException(nameof(action)); } - Action = new AnonymousAsynchronousCommandLineAction(async (context, cancellationToken) => + Action = new AnonymousAsynchronousCommandLineAction(async (context, _) => { await action(context); return 0; }); } + /// + /// Sets an asynchronous action to be run when the command is invoked. + /// + /// + /// When possible, prefer using the overload + /// and passing the parameter to the async method(s) called by the action. + /// + // Hide from intellisense, it's public to avoid the compiler choosing a sync overload + // for an async action (and fire and forget issue described in https://github.com/dotnet/command-line-api/issues/2562). + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetAction(Func> action) + { + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } + + Action = new AnonymousAsynchronousCommandLineAction(async (context, _) => + { + return await action(context); + }); + } + /// /// Sets an asynchronous action when the command is invoked. ///