in src/dsc/CliApp.cs [88:159]
private async Task<ExitCode> ExecuteAsync(string[] args, CancellationToken cancellationToken)
{
CommandLogging commandLogging = null;
try
{
commandLogging = new CommandLogging(args, this._log);
}
catch (Exception ex)
{
this._log.ExceptionAsWarning(ex);
}
// This should always be executed before anything else that outputs to console.
ConfigureConsoleCursor();
ExitCode commandResult = ExitCode.Success;
string failureReason = string.Empty;
using (CancellationTokenSource tokenSource = new CancellationTokenSource())
using (cancellationToken.Register(() => tokenSource.Cancel()))
{
var canceled = false;
void cancel()
{
if (!canceled)
{
canceled = true;
this._commandLineArgumentsManager.Command.Cleanup(); // Clean up any command-specific processes
tokenSource.Cancel();
}
};
void cancelOnCtrlC(object sender, ConsoleCancelEventArgs eventArgs)
{
_out.Warning(Resources.Warning_Cancelling);
cancel();
eventArgs.Cancel = true;
// In case something deadlocks, forcibly terminate CLI
Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith(_ =>
{
RestoreConsoleState();
Environment.Exit((int)ExitCode.ForceTerminate);
});
}
Console.CancelKeyPress += cancelOnCtrlC;
void cancelOnAssemblyUnload(AssemblyLoadContext obj)
{
cancel();
RestoreConsoleState();
}
AssemblyLoadContext.Default.Unloading += cancelOnAssemblyUnload;
try
{
(commandResult, failureReason) = await RunCommandAsync(args, tokenSource.Token);
}
catch (Exception e)
{
failureReason = this.ReportException(e);
commandResult = ExitCode.Fail;
}
finally
{
Shutdown(commandLogging, commandResult, failureReason);
Console.CancelKeyPress -= cancelOnCtrlC;
AssemblyLoadContext.Default.Unloading -= cancelOnAssemblyUnload;
}
}
return commandResult;
}