2012-05-21 9 views
5

चलाता है मैं एक स्प्लैश स्क्रीन दिखाने की कोशिश कर रहा हूं, और एप्लिकेशन को फ्रीज नहीं करता, जबकि यह किसी डेटाबेस से कनेक्ट होता है। सामान्य कनेक्शन (एडीओ के माध्यम से एमएसएसएलएल में) लगभग 300 एमसीसी लेते हैं, और इससे मुख्य थ्रेड विंडोज़ पर "प्रतिक्रिया नहीं दे रहा" दिखाता है।डेटाबेस कनेक्शन के दौरान एक स्प्लैश स्क्रीन दिखाएं (जो लंबे समय तक लग सकता है)

हालांकि (ए) नेटवर्क त्रुटि या (बी) एक कॉन्फ़िगरेशन गलती (अमान्य SQL सर्वर होस्टनाम/इंस्टेंस) के मामले में, समय-समय पर 60 सेकंड लगते हैं। यह न केवल एप्लिकेशन को गैर-उत्तरदायी बनाता है, लेकिन जब यह फ्रीज हो रहा है तो कोई त्रुटि या संदेश दिखाना लगभग असंभव है। कनेक्शन शुरू करने से पहले मैं एक संदेश पॉप अप कर सकता था लेकिन 60 सेकंड के लिए मुख्य थ्रेड ब्लॉक होने पर वास्तव में कोई समाधान नहीं होता है।

समाधान पृष्ठभूमि थ्रेड से कनेक्शन को स्थानांतरित करने के लिए प्रतीत होता है। निम्नलिखित कोड को यह नेतृत्व:

  1. एक TThread स्तरीय कि पृष्ठभूमि कनेक्शन और कुछ SyncObj बनाता है की तरह एक TEvent एक संकेत वापस मुख्य थ्रेड को भेजने के लिए इस्तेमाल किया।

  2. इस कोड के साथ मुख्य थ्रेड में एक पाश:

    BackgroundThread.StartConnecting; 
    while not BackgroundThread.IsEventSignalled do begin 
        Application.ProcessMessages; // keep message pump alive. 
    end; 
    // continue startup (reports error if db connection failed) 
    

यह सही रास्ता तय करना है? मेरे अंदर की झिझक ऊपर समाधान के निम्नलिखित तत्व होते हैं:।

ए मैं Application.ProcessMessages, जो मैं एक चरम कोड गंध पर विचार बुला लिया जाएगा (यह इस नियम के लिए एक स्वीकार्य अपवाद हो सकता है)

बी मैं एक आवेदन के स्टार्टअप में थ्रेड पेश कर रहा हूं, और मैं बग पेश करने के बारे में चिंतित हूं।

किसी को भी एक संदर्भ कार्यान्वयन कि दौड़ की स्थिति से मुक्त होने के लिए जाना जाता है, कि एडीओ करने के लिए एक पृष्ठभूमि कनेक्शन कर सकते हैं, और एक सुरक्षित दृष्टिकोण होने के लिए जाना जाता है, जो वास्तव में उपयोगी होगा। अन्यथा सामान्य सुझाव या आंशिक उदाहरण अच्छे हैं।

+5

को देखते हुए (जैसे 1000ms) है कि एक सामान्य कनेक्शन केवल 300 मि.से लेता है, यही कारण है कि समय समाप्ति को बदल नहीं? – awmross

+4

पृष्ठभूमि धागे से स्प्लैश स्क्रीन कैसे प्रदर्शित करें: http: // stackoverflow।कॉम/प्रश्न/388506/डिस्प्ले-स्प्लैश-स्क्रीन-इन-डेल्फी-कब-मुख्य-थ्रेड-व्यस्त-व्यस्त – Harriv

+1

यह समस्या मुख्य GUI थ्रेड –

उत्तर

4

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

+0

+1, सहमत हैं, लेकिन आपको सभी डेटाबेस क्रियाओं को उस थ्रेड में स्थानांतरित करने की आवश्यकता होगी, क्योंकि आप अपने कार्यकर्ता से मुख्य थ्रेड पर कनेक्शन ऑब्जेक्ट को पास नहीं कर सकते हैं। और उन्हें मुख्य थ्रेड में रखना आवश्यक है उदा। यदि आप डेटा जागरूक घटकों का उपयोग कर रहे हैं। – TLama

+1

वह कह रहा है कि आप केवल खुले हैं और फिर उस कनेक्शन को बंद करें। तो आप केवल अपने ऐप की "त्रुटि जांच" सुविधा के रूप में प्रारंभिक कनेक्शन को संभालने वाले हैं। आपको अभी भी मुख्य धागे में कनेक्शन तर्क दोबारा करना होगा। –

+0

@ वॉरेन, अगर आप केवल यह सत्यापित करने के लिए जा रहे हैं कि कनेक्ट करना संभव है और बाद में मुख्य थ्रेड में समान कनेक्शन सेटिंग्स के साथ फिर से कनेक्ट हो तो आप मेरे हटाए गए (अब वास्तव में हटाए गए) उत्तर से कोड का उपयोग कर सकते हैं। – TLama

1

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

छोटे ट्यूटोरियल here

आप थ्रेडिंग के लिए लाइब्रेरी का भी उपयोग कर सकते हैं, उदाहरण के लिए OmniThreadLibrary

+0

मुझे पता है। लेकिन मैं विशेष रूप से अपने ऐप स्टार्टअप को अवरुद्ध करने के बारे में सोच रहा हूं - मैं इसे कैसे कर सकता हूं - मेरा अपना संदेश-पंप लूपिंग (कॉलिंग एप्लिकेशन.प्रोसेस संदेश) या कुछ और? –

+0

मैंने थ्रेड में स्प्लैश स्क्रीन प्रदर्शित करना समाप्त कर दिया .. प्रश्न पर मेरी टिप्पणी में लिंक देखें। – Harriv

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