2013-11-23 8 views
6

से प्रक्रिया या धागा बदल गया है मेरे पास एक सी # .NET कंसोल एप्लिकेशन है जो SmtpClient का उपयोग करके एक ईमेल भेजता है।अंतिम चरण (विजुअल स्टूडियो)

मैं कर रहा हूँ कोड में निम्नलिखित व्यवहार नीचे दिखाया गया का अनुभव करता है:,

  1. कहीं लाइन 35
  2. तोड़ने बिंदु मारो ऊपर एक तोड़ बिंदु सेट, लाइन 30, 32 के माध्यम से कदम आदि
  3. इससे पहले कि यह लाइन 35 मारता है, इसे वापस कूदता फिर
  4. 28 लाइन अप करने के लिए कुछ बिंदु पर, मैं "प्रक्रिया या धागे अंतिम चरण के बाद से बदल गया है" मिल संदेश
  5. कूद के आसपास यादृच्छिक लगता

The process or thread has changed since last step screen shot

क्यों मेरी तोड़ने बिंदु कूद के आसपास है?

उस संदेश का क्या अर्थ है?

क्या मेरे कोड में कुछ गड़बड़ है?

(Here's another similar question on Stackoverflow। शायद एक ही बात है, लेकिन यह ASP.NET है)


प्रति हंस Passants की नोक इस प्रकार है।

इस संस्करण अभी भी परमिट रेस स्थिति: मेरी घड़ी के ईवेंट हैंडलर जबकि कोड चल रहा है फिर से entrancy से बचने के लिएTimer.AutoReset टॉगल संपत्ति।

private void OnTimerElapsed(object source, ElapsedEventArgs e) 
{ 
    timer.AutoReset = false; // prevent another Elapsed event 
    MyClass.SendMail(smtpServer, account, password); // do stuff 
    timer.AutoReset = true; // allow another Elapsed event 
} 

अंतिम संस्करण:AutoReset साथ टाइमर प्रारंभ पहले से ही गलत पर सेट है, तो Timer.Start() फिर से अपने बीत चुके ईवेंट हैंडलर के अंत में कहते हैं।

public void Start() 
{ 
    timer = new Timer(checkInterval); 
    timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed); 
    timer.AutoReset = false; // prevent race condition 
    timer.Start(); 
} 

private void OnTimerElapsed(object source, ElapsedEventArgs e) 
{ 
    bool exceptionIsNasty = false; 
    try { 
     MyClass.SendMail(smtpServer, account, password); // do stuff 
    } 
    catch (Exception ex) { 
     // Log exception, set exceptionIsNasty to true if the mailing should be stopped 
     //... 
    } 
    finally { 
     if (!exceptionIsNasty) timer.Start(); // allow another Elapsed event 
    } 
} 

उत्तर

7

आप एक से अधिक थ्रेड एक ही विधि को क्रियान्वित मिल गया है और वे सभी एक ही ब्रेकप्वाइंट मारा। जब आप स्टेपिंग जारी रखते हैं, तो डीबगर सटीक रूप से अनुमान लगा सकता है कि यह किस धागे को राज्य को दिखाना चाहिए। तो आपको बस एक चेतावनी मिलती है कि अब आप एक अलग धागे की स्थिति देख रहे हैं। स्थानीय परिवर्तनीय मान अलग-अलग होने के लिए उत्तरदायी होते हैं। पाठ्यक्रम के निष्पादन स्थान के रूप में, हाइलाइट परिवर्तन का कारण है।

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

+0

यह विधि 'स्थैतिक' है, लेकिन मैं यह मानने में सही हूं कि वही बात तब भी होगी जब यह नहीं था, और जब भी मैं एक ईमेल भेजना चाहता था तो मुझे वस्तु का एक नया उदाहरण बनाना पड़ा?साथ ही, क्या मैं यह मानने में सही हूं कि मेरे पास एक ही कोड को निष्पादित करने वाले एकाधिक धागे क्यों हैं क्योंकि मेरे पास हर 1 सेकंड फायरिंग की घटना है, और हर बार जब मैं धीरे-धीरे * F10 दबाता हूं, तो उस घटना को फिर से विधि कहा जाता है? – JohnB

+1

चाहे यह स्थिर है या नहीं प्रासंगिक है। इस विधि को कॉल करने के लिए टाइमर का उपयोग करना इस तरह की परेशानी में आने का एक बहुत अच्छा तरीका है। यदि ईमेल भेजना 1 सेकंड से अधिक समय लेता है तो आपको विधि चलाने के लिए टाइमर द्वारा शुरू किया गया * दूसरा * थ्रेड मिलेगा। बहुत ही अस्वास्थ्यकर। और जब आप विधि को एक ही चरण में अपरिहार्य रखते हैं, तो निश्चित रूप से हमेशा एक सेकंड से अधिक समय लगता है। एक दिन * अस्सी हजार * ईमेल भेजने के ज्ञान पर विचार करें। टाइमर की ऑटोरसेट संपत्ति को झूठी पर सेट करके इस पुन: प्रवेश से बचें। –

+0

टिप के लिए धन्यवाद! क्या मैंने आपके सुझाव को सही तरीके से कार्यान्वित किया है? (उपरोक्त मेरे प्रश्न के लिए अद्यतन देखें।) * बीटीडब्ल्यू, 1 सेकंड टाइमर अंतराल केवल परीक्षण उद्देश्यों के लिए था। असली दुनिया में, मेरा टाइमर बहुत कम होता है। * – JohnB

संबंधित मुद्दे