Đây là điều tôi phát hiện ra cách đây vài ngày, tôi đã xác nhận rằng nó không chỉ giới hạn trong máy của tôi từ câu hỏi này .
Cách dễ nhất để repro nó là bắt đầu một ứng dụng Windows Forms, thêm một nút và viết mã này:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Chương trình thất bại sau khi câu lệnh Exit () thực thi. Trên Windows Forms, bạn nhận được "Lỗi khi xử lý cửa sổ".
Kích hoạt gỡ lỗi không được quản lý làm cho nó phần nào rõ ràng những gì đang xảy ra. Các COM loop phương thức được thực hiện và cho phép một thông điệp WM_PAINT sẽ được chuyển giao. Đó là gây tử vong trên một hình thức xử lý.
Sự thật duy nhất tôi đã thu thập được cho đến nay là:
- Nó không chỉ giới hạn để chạy với trình gỡ lỗi. Điều này cũng thất bại mà không có một. Cũng khá kém, hộp thoại sự cố WER xuất hiện hai lần .
- Nó không có gì để làm với bitness của quá trình. Lớp wow64 khá nổi tiếng, nhưng bản dựng AnyCPU gặp sự cố theo cách tương tự.
- Nó không có gì để làm với phiên bản .NET, 4.5 và 3.5 bị lỗi theo cùng một cách.
- Mã thoát không thành vấn đề.
- Gọi Thread.S ngủ () trước khi gọi Thoát () không khắc phục được.
- Điều này xảy ra trên phiên bản 64 bit của Windows 8 và Windows 7 dường như không bị ảnh hưởng theo cùng một cách.
- Đây là hành vi tương đối mới, tôi chưa từng thấy điều này trước đây. Tôi thấy không có bản cập nhật liên quan nào được gửi qua Windows Update , mặc dù lịch sử cập nhật không còn chính xác trên máy của tôi nữa.
- Đây là hành vi phá vỡ thô bạo. Bạn sẽ viết mã như thế này trong một trình xử lý sự kiện cho AppDomain.UnhandledException và nó gặp sự cố theo cách tương tự.
Tôi đặc biệt quan tâm đến những gì bạn có thể làm để tránh sự cố này. Đặc biệt là kịch bản AppDomain.UnhandledException làm tôi bối rối; không có nhiều cách để chấm dứt chương trình .NET. Xin lưu ý rằng việc gọi Application.Exit () hoặc Form.C Đóng () không hợp lệ trong trình xử lý sự kiện cho UnhandledException, vì vậy chúng không phải là cách giải quyết.
CẬP NHẬT: Mehrdad chỉ ra rằng chủ đề hoàn thiện có thể là một phần của vấn đề. Tôi nghĩ rằng tôi đang nhìn thấy điều này và tôi cũng đang thấy một số bằng chứng cho thời gian chờ 2 giây rằng CLR đưa ra chuỗi hoàn thiện để hoàn thành việc thực thi.
Trình hoàn thiện nằm trong NativeWindow.ForceExitMessageLoop (). Có một hàm Win32 IsWindow () tương ứng với vị trí mã, bù 0x3c khi nhìn vào mã máy ở chế độ 32 bit. Có vẻ như IsWindow () đang bế tắc. Tôi không thể có được dấu vết ngăn xếp tốt cho các phần bên trong, tuy nhiên, trình gỡ lỗi nghĩ rằng cuộc gọi P / Gọi vừa được trả về. Điều này thật khó để giải thích. Nếu bạn có thể có được một dấu vết ngăn xếp tốt hơn thì tôi rất muốn nhìn thấy nó. Của tôi
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
Không có gì cao hơn lệnh gọi ForceExitMessageLoop, trình gỡ lỗi không được quản lý được bật.
This happens on the 64-bit version of Windows 8
Hans đã nói như vậy!
Exit(0)
một chút trước đây với một số Win7 64 bit, Thay đổi ExitCode
bây giờ không giúp ích gì khi sử dụng Process.GetCurrentProcess().Kill()
mà không gặp vấn đề gì