Ctrl+C and CancellationToken#
TLDR, How to enable#
Enable the feature with appRunner.UseCancellationHandlers() or appRunner.UseDefaultMiddleware().
The problem space#
Console applications should stop gracefully when the user enters Ctrl+C or Ctrl+Break.
If your app is consuming the main thread the app will not exit right away.
Traditionally, this is solved with a following steps:
- Create a
CancellationTokenSourceand make thecancellationTokenSource.Tokenavailable for the rest of the app to reference. - Subscribe to
Console.CancelKeyPressand callcancellationTokenSource.Cancel()when triggered.cancellationToken.IsCancellationRequestedwill then return true. - Check
cancellationToken.IsCancellationRequestedin any looping code and pass the token to any libraries that check it. Instead ofThread.Sleep(...), usecancellationToken.WaitHandle.WaitOne(...)orTask.Delay(..., cancellationToken)
Cancellation middleware#
When enabled, the framework will:
- set the
CommandContext.AppConfig.CancellationTokenwith a new token. - register a parameter resolver for
CancellationToken - cancel the token on
Console.CancelKepPressAppDomain.CurrentDomain.ProcessExitAppDomain.CurrentDomain.UnhandledExceptionwhenUnhandledExceptionEventArgs.IsTerminating== true
The framework checks the cancellation token before every step in the pipeline.
Using the CancellationToken#
The CancellationToken is easy to access in your commands thanks to parameter resolvers. Simply add a parameter to your command or interceptor method.
public void MigrateRecords(CancellationToken cancellationToken, List<int> ids)
{
foreach(int id in ids.TakeWhile(!cancellationToken.IsCancellationRequested))
{
MigrateRecord(id);
}
}
Tip
Remember to pass the CancellationToken to all database, web and service requests that take one.