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
CancellationTokenSource
and make thecancellationTokenSource.Token
available for the rest of the app to reference. - Subscribe to
Console.CancelKeyPress
and callcancellationTokenSource.Cancel()
when triggered.cancellationToken.IsCancellationRequested
will then return true. - Check
cancellationToken.IsCancellationRequested
in 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.CancellationToken
with a new token. - register a parameter resolver for
CancellationToken
- cancel the token on
Console.CancelKepPress
AppDomain.CurrentDomain.ProcessExit
AppDomain.CurrentDomain.UnhandledException
whenUnhandledExceptionEventArgs.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.