Gostaria de poder interceptar CTRL+ Cem um aplicativo de console C # para que eu possa executar algumas limpezas antes de sair. Qual a melhor maneira para fazer isto?
222
Consulte MSDN:
Artigo com exemplos de código:
CancelKeyPress
é mencionado apenas brevemente nos comentários. Um bom artigo é codeneverwritten.com/2006/10/…O evento Console.CancelKeyPress é usado para isso. É assim que é usado:
Quando o usuário pressiona Ctrl + C, o código no delegado é executado e o programa sai. Isso permite que você execute a limpeza chamando os métodos necessários. Observe que nenhum código após a execução do delegado.
Existem outras situações em que isso não é suficiente. Por exemplo, se o programa estiver executando cálculos importantes que não podem ser interrompidos imediatamente. Nesse caso, a estratégia correta pode ser solicitar ao programa que saia após o término do cálculo. O código a seguir fornece um exemplo de como isso pode ser implementado:
A diferença entre esse código e o primeiro exemplo é
e.Cancel
definido como true, o que significa que a execução continua após o delegado. Se executado, o programa espera que o usuário pressione Ctrl + C. Quando isso acontece, akeepRunning
variável altera o valor, fazendo com que o loop while saia. Esta é uma maneira de fazer com que o programa saia normalmente.fonte
keepRunning
pode precisar ser marcadovolatile
. Caso contrário, o encadeamento principal pode armazená-lo em cache em um registro da CPU e não notará a alteração do valor quando o delegado for executado.ManualResetEvent
vez de girar em umbool
.winpty dotnet run
). Caso contrário, o delegado nunca será executado.Eu gostaria de adicionar à resposta de Jonas . Girar em um
bool
causará 100% de utilização da CPU e desperdiçará muita energia sem fazer nada enquanto aguarda CTRL+C .A melhor solução é usar um
ManualResetEvent
para realmente "esperar" pelo CTRL+ C:fonte
Aqui está um exemplo de trabalho completo. cole no projeto de console C # vazio:
fonte
Esta pergunta é muito semelhante a:
Capturar saída do console C #
Aqui está como eu resolvi esse problema e lidei com o usuário pressionando o X e Ctrl-C. Observe o uso de ManualResetEvents. Isso fará com que o encadeamento principal fique inativo, o que libera a CPU para processar outros encadeamentos enquanto aguarda a saída ou a limpeza. NOTA: É necessário definir o TerminationCompletedEvent no final do main. Não fazer isso causa latência desnecessária na finalização devido ao tempo limite do sistema operacional ao matar o aplicativo.
fonte
Console.TreatControlCAsInput = true;
trabalhou para mim.fonte
O que é necessário no dotnet c # - o chamado token de cancelamento passado para
Host.RunAsync(ct)
e, em armadilhas de sinais de saída, para o Windows seria...
fonte