Tenho um aplicativo de console que contém muitos threads. Existem threads que monitoram certas condições e encerram o programa se forem verdadeiras. Essa rescisão pode acontecer a qualquer momento.
Preciso de um evento que possa ser disparado quando o programa estiver fechando para que eu possa limpar todos os outros threads e fechar todos os identificadores de arquivo e conexões corretamente. Não tenho certeza se já existe um integrado ao .NET framework, então estou perguntando antes de escrever o meu.
Eu estava me perguntando se houve um evento nos moldes de:
MyConsoleProgram.OnExit += CleanupBeforeExit;
Respostas:
Não tenho certeza de onde encontrei o código na web, mas agora o encontrei em um de meus projetos antigos. Isso permitirá que você faça um código de limpeza em seu console, por exemplo, quando for fechado abruptamente ou devido a um desligamento ...
Atualizar
Para quem não está verificando os comentários, parece que essa solução em particular não funciona bem (ou nem funciona) no Windows 7 . O seguinte tópico fala sobre isso
fonte
bool Handler()
devereturn false;
(não retorna nada no código) para que funcione. Se retornar verdadeiro, o Windows exibe a caixa de diálogo "Encerrar processo agora". = DExemplo completo de funcionamento, funciona com ctrl-c, fechando as janelas com X e kill:
fonte
Handler
exceto para oreturn true
e um loop while para contar os segundos. O aplicativo continua a ser executado em ctrl-c, mas fecha após 5 segundos ao fechar com o X.Handler
eliminação de processo ou desligamento", mas parece que o console fecha antes de executar a parte restante do método {using Win10, .NET Framework 4.6.1}Verifique também:
fonte
Console.CancelKeyPress
seguidaProcessExit
evento realmente levantou afinalCancelKeyPress
manipuladores de eventos de execução.Eu tive um problema semelhante, apenas meu aplicativo de console estaria executando em um loop infinito com uma instrução preemptiva no meio. Aqui está minha solução:
fonte
Parece que os threads estão encerrando o aplicativo diretamente? Talvez seja melhor ter um thread sinalizando o thread principal para dizer que o aplicativo deve ser encerrado.
Ao receber este sinal, o encadeamento principal pode encerrar de forma limpa os outros encadeamentos e, finalmente, fechar-se.
fonte
A resposta de ZeroKelvin funciona no aplicativo de console do Windows 10 x64, .NET 4.6. Para aqueles que não precisam lidar com o enum CtrlType, aqui está uma maneira realmente simples de se conectar ao desligamento do framework:
Retornar FALSE do manipulador informa ao framework que não estamos "manipulando" o sinal de controle, e a próxima função do manipulador na lista de manipuladores para este processo é usada. Se nenhum dos manipuladores retorna TRUE, o manipulador padrão é chamado.
Observe que, quando o usuário realiza um logoff ou desligamento, o retorno de chamada não é chamado pelo Windows, mas é encerrado imediatamente.
fonte
Existe para aplicativos WinForms;
Para aplicativos de console, tente
Mas não tenho certeza de em que ponto isso é chamado ou se funcionará no domínio atual. Eu suspeito que não.
fonte
Visual Studio 2015 + Windows 10
Código:
fonte
O link mencionado acima por Charle B em comentário ao flq
No fundo diz:
Em algum outro lugar do tópico, é sugerido criar uma janela oculta. Então eu crio um winform e no onload eu anexei ao console e executo o Main original. E então SetConsoleCtrlHandle funciona bem (SetConsoleCtrlHandle é chamado conforme sugerido por flq)
fonte
AllocConsole
como no seu exemplo) para mostrar algumas informações adicionais. O problema é que todo o aplicativo (todas as janelas) é fechado se o usuário clicar em (X) na janela do console. AsSetConsoleCtrlHandler
obras, mas as paradas de aplicativos de qualquer maneira antes de qualquer código no manipulador executados (I ver breakpoints demitido e direita, em seguida, as paradas de aplicativos).Para os interessados em VB.net. (Eu pesquisei na internet e não consegui encontrar um equivalente para isso) Aqui está traduzido para vb.net.
fonte