How to handle termination in System.CommandLine
Important
System.CommandLine
is currently in PREVIEW, and this documentation is for version 2.0 beta 4.
Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
To handle termination, inject a CancellationToken instance into your handler code. This token can then be passed along to async APIs that you call from within your handler, as shown in the following example:
static async Task<int> Main(string[] args)
{
int returnCode = 0;
var urlOption = new Option<string>("--url", "A URL.");
var rootCommand = new RootCommand("Handle termination example");
rootCommand.Add(urlOption);
rootCommand.SetHandler(async (context) =>
{
string? urlOptionValue = context.ParseResult.GetValueForOption(urlOption);
var token = context.GetCancellationToken();
returnCode = await DoRootCommand(urlOptionValue, token);
});
await rootCommand.InvokeAsync(args);
return returnCode;
}
public static async Task<int> DoRootCommand(
string? urlOptionValue, CancellationToken cancellationToken)
{
try
{
using (var httpClient = new HttpClient())
{
await httpClient.GetAsync(urlOptionValue, cancellationToken);
}
return 0;
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("The operation was aborted");
return 1;
}
}
The preceding code uses a SetHandler
overload that gets an InvocationContext instance rather than one or more IValueDescriptor<T>
objects. The InvocationContext
is used to get the CancellationToken
and ParseResult objects. ParseResult
can provide argument or option values.
To test the sample code, run the command with a URL that will take a moment to load, and before it finishes loading, press Ctrl+C. On macOS press Command+Period(.). For example:
testapp --url https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis
The operation was aborted
Cancellation actions can also be added directly using the CancellationToken.Register method.
For information about an alternative way to set the process exit code, see Set exit codes.