2012-03-02 6 views
16

Co stanie się, gdy przerwę moją aplikację konsoli C# z Control-C?Co się dzieje, gdy przerywam aplikację konsoli C# z Control-C?

Czy proces został zabity? Czy pamięć jest wolna? Czy są wykonywane bloki finally? Co dzieje się z połączeniami z bazą danych?

Czy to się różni, jeśli aplikacja została stworzona do debugowania lub wydania lub uruchamiania w programie Visual Studio?

Odpowiedz

11

Krótka odpowiedź: To nic nie robi po CTRL-C

Długi Odpowiedź: Jest dobry artykuł o tym na MSDN który wyraźnie stwierdza, że ​​wysyła sygnał (przerwania) zamiast naciśnięcia klawisza -events.

Wywoływane jest również cancelKeyPress-Event, które można subskrybować i robić, co chcesz!

Pechowo nie ma więcej informacji o tym, co faktycznie zostało zrobione domyślnie. Może w najgorszym przypadku możesz to sprawdzić samemu. Ale imo powinna istnieć jakaś dokumentacja o tym ...

UPDATE: Alois Kraus napisał codeproject-Article o wdzięcznie shuting dół na konsoli wniosek po otrzymaniu CTRL-C.

Cytując Alois Kraus:

Domyślne zachowanie CLR jest nic nie robić. Oznacza to, że CLR jest powiadamiany bardzo późno przez powiadomienie DLL_PROCESS_DETACH, w którym kontekście żaden zarządzany kod nie może już działać, ponieważ blokada programu ładującego OS jest już zajęta. Pozostaje nam niefortunna sytuacja, że ​​nie otrzymujemy żadnych powiadomień ani nie uruchamiamy żadnych finalizatorów. Wszystkie wątki są cicho zabijane bez szansy na wykonanie ich bloków catch/finally w celu uporządkowanego wyłączenia. Powiedziałem w pierwszym zdaniu domyślnie, ponieważ istnieje sposób, by z wdziękiem obsłużyć tę sytuację. Klasa Console ma nowego członka wydarzenia z .NET 2.0: Console.CancelKeyPress. Umożliwia otrzymywanie powiadomień o klawiszach Ctrl-C i Ctrl-Break, w których można zatrzymać zamykanie (tylko dla Ctrl-C, ale nie Ctrl-Break). Główny problem polega na tym, że jeśli przechwycisz zdarzenie Ctrl-C/Break i wyjdziesz z programu obsługi, nie będzie wywoływanych żadnych finalizatorów. To nie jest to, co nazwałbym spółdzielczym zamknięciem. Pierwszą rzeczą, która przychodzi mi do głowy, jest wywołanie Environment.Exit, ale nie wywołuje ona żadnych finalizatorów. Nie wszystko jest stracone. Wymyśliłem brudną sztuczkę, aby uruchomić wszystkie finalizatory: rozpoczynamy wątek pomocnika wewnątrz programu obsługi zdarzeń, który następnie wywołuje Environment.Exit. Voila, nasi finaliści nazywają się.

Powiązane problemy