2015-05-24 23 views
31

Niedawno wystąpił problem z wierszem polecenia w systemie Windows, w którym włączony był tryb QuickEdit, a kliknięcie okna wybierało tekst i zawieszało działający program. To jest, oczywiście, znany zachowanie, znalazłem kilka pytań z nim związanych:Jak i dlaczego tryb QuickEdit w wierszach polecenia powoduje zamrożenie aplikacji?

Jak jest aplikacja "wstrzymana"/"zawieszony"? Czy proces jest podobny do sygnału SIGSTOP w * nix? (Interesuje mnie również zrozumienie, dlaczego ta funkcja istnieje w pierwszej kolejności? Wydaje się nieintuicyjna i niebezpieczna.)

+1

Niestety, nie mogę ci powiedzieć, jak. Dla "Dlaczego?": Mogę sobie wyobrazić, że trudno jest wybrać tekst podczas przewijania. – Stephan

+1

Odpowiada to dość dobrze: http://superuser.com/questions/459609/what-does-it-do-exactly-if-i-click-in-the-window-of-cmd –

+0

@ScottC good find , dzięki! Jednak naprawdę staram się zrozumieć, jak pod maską (i chciałbym wiedzieć, * dlaczego *). Również pewne porównanie z * nix. – Whymarrh

Odpowiedz

31

Jest to bardzo zgodne z projektem. Nie ma rozsądnego sposobu, w jaki użytkownik może wybrać tekst, gdy program ciągle przewija zawartość okna konsoli. Tak więc program hosta konsoli po prostu przestaje czytać dane wyjściowe stdout/stderr, a twój program zawiesza się, dopóki użytkownik nie wykona operacji. Można to zmienić, musisz zadzwonić pod numer Get+SetConsoleMode() i wyłączyć opcję ENABLE_QUICK_EDIT_MODE.

Należy zauważyć, że to "zawieszenie się" nie różni się zasadniczo od przerw w realizacji uzyskanych, gdy program generuje standardowe wyjście z szybkością znacznie wyższą niż host konsoli może ją zużyć. Chociaż te opóźnienia są ograniczone.

I nie jest to jedyny sposób, w jaki użytkownik może zatrzymać twój program, może też po prostu nacisnąć Ctrl + S. Naciśnięcie Ctrl + Q wznawia je ponownie. Jeśli jesteś wystarczająco dorosły, możesz rozpoznać te kody kontrolne jako Xon/Xoff, znaki handshake dla terminala. Tak naprawdę jest konsola, prosta emulacja terminala, tak jak były używane w latach siedemdziesiątych. Można to również zmienić, musisz przestać polegać na wbudowanym buforowanym wejściu konsoli i przejść na ReadConsole(). Lub wyłączając opcję ENABLE_LINE_INPUT console, nie mając pewności, jakie efekty uboczne, od kiedy nie wspomniałeś o żadnym środowisku uruchomieniowym języka, musisz spróbować.

Oczywiście zakończenie programu jest bardzo proste. Otrzymasz EOF na stdin, gdy użytkownik wpisze Ctrl + Z, który powinien zakończyć twój program. Istnieje również Ctrl + C i Ctrl + Break do natychmiastowego zakończenia, niezależnie od tego, co robi twój program. Możesz otrzymać powiadomienie o nich za pomocą SetConsoleCtrlHandler(), ale nie możesz tego zablokować.

Jeśli domyślnym zachowaniem jest niebezpieczna i ryzyko dla zdrowia człowieka, to zdecydowanie sugeruję zatrudnić konsultanta. I nie będzie wiedział, kto napisał tę odpowiedź.

+0

Dzięki! Z pewnością miałem na myśli "niebezpieczny" w tym sensie, że może powodować problemy. Porównujesz pauzę z zachowaniem, jakie program wykazuje podczas generowania wyjścia zbyt szybko, co oznacza, że ​​wykonanie zatrzymuje się na 'Console.WriteLine', dopóki wybór nie zostanie dokonany? – Whymarrh

+0

Tak. Dokładnie tego, którego nie możesz znać. –

+0

To musi być jakoś związane z projektem Windowsa i pewnymi problemami związanymi z kompatybilnością, ale wciąż na każdym Linuxie można po prostu wybrać tekst z terminala i program się nie zatrzymuje. –

0

Miałem wiele problemów ze stwierdzeniem, dlaczego moja aplikacja C# nie odpowiedziała, dopóki nie nacisnąłem klawisza! Dla każdego, kto potrzebuje programowego wyłączenia QuickEdit, spójrz na here.