Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Attempt to solve issue #22 - but this needs to be clarified
- Loading branch information
Showing
3 changed files
with
84 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Spectre.Console.Cli; | ||
|
||
namespace tone.DependencyInjection; | ||
|
||
public abstract class CancellableAsyncCommand<TSettings> : AsyncCommand<TSettings> | ||
where TSettings : CommandSettings | ||
{ | ||
private readonly ConsoleAppCancellationTokenSource _cancellationTokenSource = new(); | ||
|
||
public abstract Task<int> ExecuteAsync(CommandContext context, TSettings settings, CancellationToken cancellation); | ||
|
||
public sealed override async Task<int> ExecuteAsync(CommandContext context, TSettings settings) => await ExecuteAsync(context, settings, _cancellationTokenSource.Token); | ||
} |
42 changes: 42 additions & 0 deletions
42
tone/DependencyInjection/ConsoleAppCancellationTokenSource.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using System.Threading; | ||
|
||
namespace tone.DependencyInjection; | ||
|
||
internal class ConsoleAppCancellationTokenSource | ||
{ | ||
private readonly CancellationTokenSource _cts = new(); | ||
|
||
public CancellationToken Token => _cts.Token; | ||
|
||
public ConsoleAppCancellationTokenSource() | ||
{ | ||
Console.CancelKeyPress += OnCancelKeyPress; | ||
AppDomain.CurrentDomain.ProcessExit += OnProcessExit; | ||
|
||
using var _ = _cts.Token.Register(() => | ||
{ | ||
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit; | ||
Console.CancelKeyPress -= OnCancelKeyPress; | ||
}); | ||
} | ||
|
||
private void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e) | ||
{ | ||
// NOTE: cancel event, don't terminate the process | ||
e.Cancel = true; | ||
|
||
_cts.Cancel(); | ||
} | ||
|
||
private void OnProcessExit(object? sender, EventArgs e) | ||
{ | ||
if (_cts.IsCancellationRequested) | ||
{ | ||
// NOTE: SIGINT (cancel key was pressed, this shouldn't ever actually hit however, as we remove the event handler upon cancellation of the `cancellationSource`) | ||
return; | ||
} | ||
|
||
_cts.Cancel(); | ||
} | ||
} |