2011-01-26 29 views
12

के दौरान अपवादों को निगलने वाला एक WPF विंडो संवाद विंडो क्लास में ShowDialog विधि का उपयोग करके दिखाया जाता है जैसे कि मुख्य विंडो पर बटन दबाया जाता है।WPF ShowDialog विंडो लोड

 private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      try 
      { 
       var window = new Window1(); 
       window.ShowDialog(); 
      } 
      catch (ApplicationException ex) 
      { 
       MessageBox.Show("I am not shown."); 
      } 
     } 

खिड़की एक लोडेड घटना इस तरह XAML में सदस्यता ली है:

<Window x:Class="Stackoverflow.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Loaded="Window_Loaded"> 
    <Grid /> 
</Window> 

एक अपवाद Window_Loaded घटना

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     throw new ApplicationException(); 
    } 

हालांकि अपवाद द्वारा catched नहीं है में फेंक दिया जाता है ShowDialog कॉल के आस-पास पकड़ो, न ही कॉल रिटर्न। अपवाद निगल लिया गया है और खिड़की अभी भी प्रदर्शित है।

ऐसा क्यों होता है और मैं एक WPF विंडो की विंडो_लोडेड घटना में अपवाद को संभालने के बारे में कैसे जाउंगा? क्या मुझे इसे ईवेंट-हैंडलर में पकड़ना है और विंडो को मैन्युअल रूप से निपटाना है?

WinForms में आप क्रम ShowDialog के माध्यम से कॉल अपवाद बुलबुला जाने के लिए में Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)

कॉल करने के लिए की जरूरत है। क्या ऐसा कोई स्विच है जिसे WPF पर सेट करने की आवश्यकता है?

+0

मैं अपनी स्थिति पुन: पेश करने की कोशिश की, लेकिन कोई सफलता के साथ। अपवाद सामान्य तरीके से पकड़े जाते हैं। मुझे लगता है कि आपने कोड को सरल बना दिया है, लेकिन ऐसा लगता है कि मुख्य बिंदु विवरण में है। उन्हें प्रदान करें और मैं मदद करने की कोशिश करूंगा। –

+0

पुन: पेश करने की कोशिश करने के लिए धन्यवाद। मैंने समस्या को बहुत सरल उदाहरण में पुन: उत्पन्न किया है जहां से मैंने पोस्ट स्रोत कोड लिया था। मैं वीएस -2010 का उपयोग कर रहा हूँ। मैं अपना प्रश्न संपादित करूंगा और पुन: उत्पन्न करने के लिए कुछ प्रासंगिक जानकारी जोड़ूंगा। – vidstige

उत्तर

7

मैंने इस समस्या को x64 मशीनों पर देखा है, जिसमें किसी भी सीपीयू के साथ संकलित कोड है। x84 के रूप में संकलित करने के लिए आपके प्रोग्राम को बदलना इसे ठीक कर सकता है, लेकिन मुझे हमारी असेंबली के आधार पर स्वयं समस्याएं आई हैं।
मेरा एकमात्र कोड सुझाव निम्न है, और फिर भी इसे लेने की गारंटी नहीं है। अपवाद को पकड़ें, और इसे पृष्ठभूमि कार्यकर्ता में फिर से फेंक दें।

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    try 
    { 
     /// your code here... 
     throw new ApplicationException(); 
     /// your code here... 
    } 
    catch (Exception ex) 
    { 
     if (IntPtr.Size == 8) // 64bit machines are unable to properly throw the errors during a Page_Loaded event. 
     { 
      BackgroundWorker loaderExceptionWorker = new BackgroundWorker(); 
      loaderExceptionWorker.DoWork += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { runWorkerCompletedEventArgs.Result = runWorkerCompletedEventArgs.Argument; }); 
      loaderExceptionWorker.RunWorkerCompleted += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { throw (Exception)runWorkerCompletedEventArgs.Result; }); 
      loaderExceptionWorker.RunWorkerAsync(ex); 
     } 
     else 
      throw; 
    } 
} 
+0

वाह, यह काम किया ... यह वास्तव में अजीब और डरावना है। मुझे नहीं लगता कि मैं अब इसके बारे में अधिक जानना चाहता हूं। :) मैंने सोचा कि यह एक डब्ल्यूपीएफ डिजाइन था। आपका बहुत बहुत धन्यवाद! – vidstige

+4

ओह, एक sidenote फिर से अपवाद फेंक नहीं है जैसे "पूर्व फेंक;" - पुनर्स्थापित करने के लिए बेहतर है। इस तरह "फेंक" की तरह। – vidstige

+0

मैंने फेंक दिया "पूर्व"।यह किसी और चीज की तुलना में स्पष्टता के लिए और अधिक था। हमारे पास एक स्थिति है, जहां IntPtr.Size एक x64 मशीन पर 4 लौटाता है और किसी अन्य असेंबली से रिफ्लेसीटन के माध्यम से विंडो लोड करते समय अपवाद अभी भी खोला जाता है, इसलिए मैं यह नहीं कहूंगा कि यह 100% समाधान है। अगर कथन को हटाया जाए तो यह ठीक होगा। – midspace

0

मुझे इसी तरह की समस्या है, और यह समझने की कोशिश कर रहा है कि यह कहां आ रहा है निराशाजनक है। ऐसी कुछ चीजें हैं जो समस्या पैदा कर सकती हैं।

  • क्या आप विधि कॉल प्रारंभिक कॉम्पोनेंट() से पहले कुछ भी कॉल कर रहे हैं; ? पहले मेरे पास xaml तत्वों को कॉल करने का एक तरीका था, जिसे अभी तक प्रारंभ नहीं किया गया है।
  • क्या आपने चरण शुरू करने के लिए F10 दबाकर एप्लिकेशन को शुरू करने का प्रयास किया है, तो आपको सटीक प्रक्रिया शुरू होने देगी?
  • क्या आपने अपना नामकरण चेक किया है? एक्सएएमएल त्रुटियों को निगल सकता है जैसे विधियों को गलत वर्तनी कहा जा रहा है, और फिर रनटाइम पर एक अपवाद फेंक दिया जाता है, यह विशेष रूप से सही डेटासेट प्रदाताओं। आप आश्चर्यचकित होंगे कि आप किसके साथ दूर हो सकते हैं।
  • एक फॉर्म खोलने के लिए अपवाद को पकड़ना बहुत मौलिक है, मैं किसी भी आश्रित (डेटा या एक्सएएमएल बाइंडिंग) को देखता हूं और पहले उनसे निपटता हूं।

आशा उन बिंदुओं मदद .......

+0

* प्रश्न में बताए गए अलावा कोई अन्य मेटोड दिखाया नहीं गया है। InitializeComponents दोनों खिड़कियों के निर्माता में अकेला है। – vidstige

+0

* अच्छा बिंदु। मुझे लगता है कि संवाद से पहले फेंकने वाले सभी कोड को चलाने का एक तरीका था। – vidstige

1

मैं भी एक खाली WPF 3.5 परियोजना में दृश्य स्टूडियो 2010 में अपना जवाब पुनर्गठन किया गया।

प्रोजेक्ट अपेक्षित व्यवहार करता है, यानी विंडो_लोडेड ने अपवाद फेंक दिया, और यह बटन क्लिक ईवेंट द्वारा पकड़ा गया।

तो मुझे यकीन नहीं है कि आपका काम क्यों नहीं कर रहा है, शायद अपने App.xml.cs और किसी अन्य कोड को पोस्ट करने का प्रयास करें जिसे आपने यहां नहीं दिखाया है?

इस बीच में, मैंने सोचा कि मैं कुछ चीजें बाहर बिंदु होगा:

WPF वास्तव में WinForms से थोड़ी अलग है "ध्यान में न आया" अपवाद का क्या करता है। एक स्टार्टर के लिए इस पर देखने का प्रयास करें:

http://msdn2.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx

ऐसा लगता है कि वहाँ SetUnhandledExceptionMode विधि के लिए WPF में एक सटीक बराबर नहीं है (http://social.msdn.microsoft.com/forums/en-US/wpf/thread/955c75f8-9cd9-4158-bed9-544bd7946413 देखें)।एक हैंडलर पंजीकरण करने के बारे में उनकी सलाह आज़माएं और देखें कि क्या यह आपकी मदद करता है?

मैं आपके कोड के माध्यम से कदम उठाने की अनुशंसा करता हूं - विंडो_लोडेड में ब्रेकपॉइंट सेट करें, और देखें कि क्या होता है - कॉल स्टैक पर सावधानीपूर्वक ध्यान दें।

शुभकामनाएं!

1

यह थोड़ा और अधिक शोध करते हुए मुझे यह असाधारण ब्लॉगग एंट्री एक समान समस्या का वर्णन करती है।

http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/

यह पता चला है के रूप में यह एक 64-बिट प्रोसेसर आर्किटेक्चर समस्या हो सकती है। किसने अनुमान लगाया होगा ?! यह समझा सकता है कि क्यों कुछ लोग इस मुद्दे को मेरे सरल उदाहरण को पुन: उत्पन्न नहीं कर सके। मैंने अपना उदाहरण "कोई भी CPU", x64 और x86 में संकलित करने का प्रयास किया लेकिन इसका कोई फायदा नहीं हुआ। X64 पर पूरी चीज वास्तव में एक विंडोज क्रैश संवाद के साथ पूरी तरह से दुर्घटनाग्रस्त हो गई।

तो मुझे लगता है कि 32-बिट मशीन पर इसे सत्यापित किए बिना यह उत्तर है।

2

"क्यों" यहाँ समझाया गया है: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/

संक्षेप में, अपवाद 64-बिट ऑपरेटिंग सिस्टम में प्रचारित नहीं किया जा सकता उपयोगकर्ता और कर्नेल मोड के बीच एक संक्रमण है क्योंकि वहाँ।

@ मिडस्पेस उत्तर में IntPtr.Size का परीक्षण पर्याप्त नहीं है क्योंकि IntPtr.Size x64 os पर चल रहे x86 प्रक्रिया में 4 के बराबर होगा (आपको .NET 4 और इससे अधिक के बजाय Environment.Is64BitOperatingSystem का उपयोग करने की आवश्यकता है)।

समाधान अब: ContentRendered जैसे किसी अन्य ईवेंट का उपयोग करें जिसे Loaded एक के बाद बुलाया गया है या अपना कोड विंडो कन्स्ट्रक्टर में रखा गया है।

कभी भी Loaded (या OnLoad विनफॉर्म में) का उपयोग न करें, क्योंकि यदि वहां कोई अपवाद है, तो आप नहीं जानते कि क्या हो सकता है।

इस जवाब पर भी एक नज़र डालें: https://stackoverflow.com/a/4934010/200443