क्यों पर्यावरण। Exit () किसी भी अधिक कार्यक्रम को समाप्त नहीं करता है?


134

यह कुछ ऐसा है जिसे मैंने कुछ दिनों पहले ही खोजा था, मुझे पुष्टि मिली कि यह इस प्रश्न से सिर्फ मेरी मशीन तक सीमित नहीं है ।

विंडोज फॉर्म एप्लिकेशन शुरू करने से इसे रीप्रो करने का सबसे आसान तरीका है, एक बटन जोड़ें और इस कोड को लिखें:

    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("yada");
        Environment.Exit(1);         // Kaboom!
    }

एक्ज़िट () स्टेटमेंट निष्पादित होने के बाद प्रोग्राम विफल हो जाता है । विंडोज फॉर्म पर आपको "विंडो हैंडल बनाने में त्रुटि" मिलती है।

अप्रबंधित डिबगिंग को सक्षम करने से यह स्पष्ट हो जाता है कि क्या चल रहा है। कॉम मोडल पाश को क्रियान्वित करने और एक WM_PAINT संदेश दिया जा करने की अनुमति देता है। यह एक विवादास्पद रूप पर घातक है।

मैंने अभी तक जितने भी तथ्य इकट्ठे किए हैं, वे हैं:

  • यह केवल डिबगर के साथ चलने तक सीमित नहीं है। यह भी एक के बिना विफल रहता है। बल्कि खराब तरीके से, WER क्रैश डायलॉग दो बार दिखाता है ।
  • इस प्रक्रिया की कड़वाहट से इसका कोई लेना-देना नहीं है। Wow64 परत बहुत कुख्यात है, लेकिन एक AnyCPU बिल्ड उसी तरह क्रैश करता है।
  • इसका .NET वर्जन, 4.5 और 3.5 से कोई लेना-देना नहीं है।
  • निकास कोड कोई मायने नहीं रखता।
  • Exit () कॉल करने से पहले Thread.Sleep () को कॉल करना इसे ठीक नहीं करता है।
  • यह विंडोज 8 के 64-बिट संस्करण पर होता है, और विंडोज 7 उसी तरह प्रभावित नहीं होता है।
  • यह अपेक्षाकृत नया व्यवहार होना चाहिए, मैंने पहले ऐसा नहीं देखा। मुझे विंडोज अपडेट के माध्यम से कोई प्रासंगिक अपडेट नहीं दिया गया है , यद्यपि कि अपडेट इतिहास मेरी मशीन पर सटीक नहीं है।
  • यह घोर तोड़ व्यवहार है। आप AppDomain.UnhandledException के लिए ईवेंट हैंडलर में इस तरह कोड लिखेंगे, और यह उसी तरह क्रैश हो जाएगा।

मुझे विशेष रूप से दिलचस्पी है कि आप इस दुर्घटना से बचने के लिए क्या कर सकते हैं। विशेष रूप से AppDomain.UnhandledException परिदृश्य मुझे स्टंप करता है; .NET प्रोग्राम को समाप्त करने के बहुत सारे तरीके नहीं हैं। कृपया ध्यान दें कि कॉलिंग Application.Exit () या Form.Close () UnhandledException के लिए ईवेंट हैंडलर में मान्य नहीं हैं, इसलिए वे वर्कअराउंड नहीं हैं।


अद्यतन: मेहरदाद ने बताया कि अंतिम धागा समस्या का हिस्सा हो सकता है। मुझे लगता है कि मैं इसे देख रहा हूं और 2 सेकंड के समय के लिए कुछ सबूत भी देख रहा हूं कि सीएलआर अंतिम रूप देने के लिए अंतिम थ्रेड देता है।

अंतिम रूप NativeWindow.ForceExitMessageLoop () के अंदर है। वहाँ एक IsWindow () Win32 समारोह है कि मोटे तौर पर कोड स्थान के साथ मेल खाती है, 0x3c ऑफसेट जब 32-बिट मोड में मशीन कोड को देखते हैं। ऐसा लगता है कि IsWindow () गतिरोध है। मुझे आंतरिक लोगों के लिए एक अच्छा स्टैक ट्रेस नहीं मिल सकता है, लेकिन डिबगर को लगता है कि पी / इनवोक कॉल अभी लौटा है। यह समझाना कठिन है। यदि आप एक बेहतर स्टैक ट्रेस प्राप्त कर सकते हैं तो मैं इसे देखना पसंद करूंगा। मेरी:

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 कॉल के ऊपर कुछ भी नहीं, अप्रबंधित डिबगर सक्षम है।


2
मैंने सिर्फ .NET 4, 4 क्लाइंट प्रोफाइल, 3.5, 3.5 क्लाइंट प्रोफाइल, 3.0 और 2.0 के साथ यह कोशिश की, और उनमें से किसी पर भी त्रुटि नहीं मिली। VS2010 का उपयोग करते हुए 64-बिट विंडोज 7 मेरा ओएस है।
स्टीव

2
@ सचे This happens on the 64-bit version of Windows 8हंस ने कहा है!
परिमल राज

7
मैं इसे (8 विन, 64-बिट्स) को रीप्रो कर सकता हूं, अपने कोड को कॉपी / पेस्ट कर सकता हूं और एक बटन को तार कर सकता हूं और मुझे सटीक वर्णन मिलता है।
कीबोर्ड

3
कंसोल मोड ऐप इस समस्या को प्रदर्शित नहीं कर सकता है, बाहर निकलें () संदेशों को पंप करते समय कुछ भी गलत नहीं हो सकता है।
हंस पैजेंट

3
मैं Exit(0)कुछ 64bit Win7 के साथ कुछ समय पहले इस तरह के व्यवहार का सामना कर चुका हूं , बिना किसी समस्या के काम ExitCodeकरने में अब इसका उपयोग करने में मदद नहीं मिली हैProcess.GetCurrentProcess().Kill()
श्रीराम सक्थिवेल

जवाबों:


85

मैंने इस समस्या के बारे में Microsoft से संपर्क किया और लगता है कि उसने भुगतान किया है। कम से कम मैं यह सोचना चाहूंगा कि यह :)। हालाँकि, मुझे उनसे किसी रिज़ॉल्यूशन की पुष्टि नहीं मिली, विंडोज ग्रुप से सीधे संपर्क करना मुश्किल है और मुझे एक मध्यस्थ का उपयोग करना पड़ा।

विंडोज अपडेट के माध्यम से दिए गए अपडेट से समस्या हल हो गई। दुर्घटना से पहले ध्यान देने योग्य 2 सेकंड की देरी अब मौजूद नहीं है, दृढ़ता से सुझाव देते हुए कि IsWindow () गतिरोध हल हो गया। और कार्यक्रम साफ और मज़बूती से बंद हो जाता है। विंडोज डिफेंडर, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll और wintb.dll के लिए अद्यतन स्थापित पैच

Uxtheme.dll ऑड-डक आउट है। यह एपीआई को प्रदर्शित करने वाली विज़ुअल स्टाइल्स को लागू करता है और इस परीक्षण कार्यक्रम द्वारा उपयोग किया जाता है। मुझे यकीन नहीं हो रहा है, लेकिन मेरा पैसा उस समस्या के स्रोत के रूप में है। C: \ WINDOWS \ system32 की प्रतिलिपि में संस्करण संख्या 6.2.9200.16660 है, जो मेरी मशीन पर 14 अगस्त, 2013 को बनाई गई थी।

मामला समाप्त।


11
Windows अद्यतन इतिहास अब मेरी मशीन पर सटीक नहीं है। मुझे पता है कि यह 14 अगस्त को स्थापित हो गया है।
हंस पसंत

51

मुझे नहीं पता कि यह "कोई और अधिक" क्यों काम नहीं करता है , लेकिन मुझे लगता है कि Environment.Exitलंबित फाइनल को निष्पादित करता है। Environment.FailFastऐसा नहीं करता।

यह हो सकता है कि (कुछ विचित्र कारण के लिए) आपके पास अजीब लंबित फाइनल हो, जो बाद में चलना चाहिए, जिससे ऐसा हो सके।


2
आप संभवतया किसी काम में लगे हो सकते हैं। अंतिम रूप से NativeWindow.ForceExitMessageLoop () निष्पादित करने में व्यस्त है। अजीब तरह से यह किसी भी कॉल में नेस्टेड नहीं है।
हंस पैसेंट

@ हंसपसंद: काश मैं इस मुद्दे को दोहरा सकता था, इसलिए मैं इस पर गौर कर सकता था, लेकिन मैं नहीं कर सकता। क्या कॉल NativeWindow.ForceExitMessageLoopप्रबंधित या अप्रबंधित कोड में अटक गई है? क्या यह भी अटक गया है, या यह व्यस्त-प्रतीक्षा कर रहा है या संदेश या कुछ और की प्रतीक्षा कर रहा है?
user541686

यह निश्चित रूप से मुख्य समस्या की ओर इशारा करता है। मुझे लगता है कि यह IsWindow () winapi फ़ंक्शन है जो समस्या की जड़ में है। मुझे लगता है कि मैं फाइनल थ्रेड पर 2 सेकंड टाइमआउट भी देख रहा हूं, जिसके बाद यह सब नरक में जाता है। डिबगर नहीं करता है दिखाने के यह IsWindow () कॉल को क्रियान्वित करने, लेकिन मैं ढेर के साथ विंडोज खेलने चाल देखा है से पहले, यह पता स्विचन जब विंडोज के अंदर महत्वपूर्ण कोड दर्ज।
हंस पैसेंट

4
मुझे लगता है कि पर्यावरण। फेलस्ट () विधि, बिना किसी अपवाद के दिए गए मामले के लिए, शायद वैसे भी उपयोग करने के लिए सबसे अच्छी विधि है। (मैं इसके बारे में पता नहीं था - धन्यवाद!) हालांकि वहाँ विरासत कोड का एक बहुत कुछ है जो पर्यावरण का उपयोग करेगा। बाहर निकलें () जो दुर्भाग्य से दुर्घटनाग्रस्त हो जाएगा :(
इयान Yates

2
आप निश्चित रूप से किसी चीज़ पर सबसे अधिक हैं। मेरे मामले में, मैंने कुछ एकीकरण परीक्षण करने के लिए IHost.StartAsync का उपयोग करके एक IHost शुरू किया था, और फिर भी कॉल करने के बाद (और निश्चित रूप से प्रतीक्षा कर रहा है) IHost.StopAsync, प्रक्रिया अभी भी समाप्त नहीं हुई। IHost.Dispose पर कॉल करने के बाद ही प्रक्रिया समाप्त होती है। टिप के लिए धन्यवाद
माल्ट आर

6

यह स्पष्ट नहीं करता है कि ऐसा क्यों हो रहा है, लेकिन मैं Environment.Exitआपके नमूने की तरह एक बटन ईवेंट हैंडलर में कॉल नहीं करूंगा - इसके बजाय मुख्य रूप को बंद कर दूं जैसा कि रेने के जवाब में सुझाया गया है ।

एक AppDomain.UnhandledExceptionहैंडलर के रूप में, शायद आप Environment.ExitCodeकॉल करने के बजाय बस सेट कर सकते हैं Environment.Exit

मुझे यकीन नहीं है कि आप यहां क्या हासिल करने की कोशिश कर रहे हैं। आप Windows प्रपत्र एप्लिकेशन से एक निकास कोड क्यों वापस करना चाहते हैं? आमतौर पर एग्जिट कोड का उपयोग कंसोल एप्लिकेशन द्वारा किया जाता है।

मुझे विशेष रूप से इस बात में दिलचस्पी है कि आप संभवतः इस क्रैश कॉलिंग पर्यावरण से बचने के लिए क्या कर सकते हैं। WER संवाद को दिखाने से रोकने के लिए Exit () आवश्यक है।

क्या आपके पास मुख्य विधि में एक कोशिश / पकड़ है? Windows प्रपत्र अनुप्रयोगों के लिए मेरे पास हमेशा संदेश लूप के साथ-साथ अनहेल्ड अपवाद हैंडलर के आसपास एक कोशिश / पकड़ होती है।


बहुत यकीन है कि आप के Application.Exitबजाय कॉल करने वाले हैं Environment.Exit
user541686

7
क्षमा करें, यह वर्कअराउंड नहीं है। WER संवाद को दिखाने से रोकने के लिए Environment.Exit () कॉल करना आवश्यक है। "ज्ञात तथ्य" पर भी ध्यान दें, निकास कोड कोई मायने नहीं रखता।
हंस पासेंट

7
@ हंस: पहले स्थान पर वैध संवाद से बचने के लिए AppDomain.UnhandledException को पकड़ने की कोशिश कर रहा है? मेरा मतलब है, अगर कोई अपवाद नहीं है, तो WER संवाद दिखाना चाहिए ?
हैरी जॉन्सटन

2

हमें अपने ऐप में समान समस्या मिली है, हमने इसे निम्न निर्माण के साथ हल किया है:

Environment.ExitCode=1;
Application.Exit();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.