Це те, що я виявив лише кілька днів тому, я отримав підтвердження, що це питання не обмежується моєю машиною з цього питання .
Найпростіший спосіб спростити це - запустивши програму Windows Forms, додати кнопку та написати цей код:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Програма не працює після виконання оператора Exit (). У Windows Forms ви отримуєте "Помилка створення ручки вікна".
Увімкнення некерованої налагодження дозволяє дещо зрозуміти, що відбувається. COM цикл модальний виконує і дозволяє повідомлення WM_PAINT бути доставлено. Це фатально для розміщеної форми.
Єдині факти, до яких я зібрався, - це:
- Це не лише обмеження роботи з налагоджувачем. Це також провалюється без одного. А також погано діалогове вікно аварії WER відображається двічі .
- Це не має нічого спільного зі шматочком процесу. Шар wow64 є досить горезвісним, але збірка AnyCPU виходить з ладу таким же чином.
- Це не має нічого спільного з версією .NET, 4.5 і 3.5 збій так само.
- Вихідний код не має значення.
- Виклик Thread.Sleep () перед викликом Exit () не виправляє це.
- Це відбувається в 64-бітній версії Windows 8, і на Windows 7, схоже, це не впливає однаково.
- Це має бути відносно нова поведінка, я цього раніше не бачив. Я не бачу жодних відповідних оновлень, що надходять через Windows Update , хоча історія оновлень більше не є точною на моїй машині.
- Це грубо порушує поведінку. Ви б написали подібний код у обробнику подій для AppDomain.UnhandledException, і він виходить з ладу таким же чином.
Мене особливо цікавить, що ви могли зробити, щоб уникнути цієї аварії. Особливо сценарій AppDomain.UnhandledException мене натикає; Існує не так багато способів припинити програму .NET. Зауважте, що виклик Application.Exit () або Form.Close () не дійсний в обробці подій для UnhandledException, тому вони не є обхідними способами.
ОНОВЛЕННЯ: Мехрдад зазначив, що нитка фіналізатора може бути частиною проблеми. Я думаю, що я бачу це, а також бачу деякі докази за 2 секунди часу, що CLR дає нитку фіналізатора для завершення виконання.
Фіналізатор знаходиться всередині NativeWindow.ForceExitMessageLoop (). Там функція IsWindow () Win32, яка приблизно відповідає розташуванню коду, зміщення 0x3c при перегляді машинного коду в 32-бітному режимі. Здається, що IsWindow () заходить у глухий кут. Я не можу отримати хороший слід стека для внутрішніх служб, проте, налагоджувач вважає, що виклик P / Invoke щойно повернувся. Це важко пояснити. Якщо ви можете отримати кращий слід стека, я хотів би це побачити. Шахта:
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.ForceExitMessageLoop() + 0x3c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Finalize() + 0x16 bytes
[Native to Managed Transition]
kernel32.dll!@BaseThreadInitThunk@12() + 0xe bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Ніщо вище виклику ForceExitMessageLoop, увімкнено некерований налагоджувач.
This happens on the 64-bit version of Windows 8
Ганс так сказав!
Exit(0)
трохи раніше тому стикався з такою поведінкою із 64-бітним Win7. Зміна ExitCode
не допомагає використовувати Process.GetCurrentProcess().Kill()
без проблем це працює