2009-04-15 33 views
6

हमारे पास कई फ्रेमों का एक जीयूआई है जो उनकी सामग्री को गतिशील रूप से बनाते हैं। प्रत्येक फ्रेम इनपुट फ़ील्ड के रूप में उपयोग किए जाने के लिए पैनल, लेबल, संपादन, comboboxes आदि बनाता है। यह बहुत अच्छी तरह से काम कर रहा है और हम प्रत्येक फ्रेम को अलग-अलग धागे में अपनी सामग्री बनाने की योजना बनाने की भी योजना बना रहे हैं।डेल्फी Win32: गतिशील रूप से बनाए गए नियंत्रण (अभिभावक संपत्ति)

हालांकि एक बड़ी समस्या है: यह धीमी है! नियंत्रण बनाना कोई समय नहीं लेता है लेकिन माता-पिता की संपत्ति को सेट करना बहुत समय लगता है।

मैंने प्रक्रिया को तेज करने के कई तरीकों की कोशिश की है लेकिन बिना किसी किस्मत के। मैंने सक्षम = गलत, दृश्यमान = गलत, अक्षम करने योग्य, लॉकविंडो अपडेट, WM_SETREDRAW की कोशिश की है ... लेकिन कुछ भी नियंत्रण के अभिभावक को स्थापित करने की समय लेने वाली प्रक्रिया को प्रभावित नहीं करता है।

भले ही हम धागे का उपयोग करते हैं, इसमें समय लगेगा क्योंकि वीसीएल कार्यों को सिंक्रनाइज़ के भीतर बुलाया जाना चाहिए।

क्या निर्माण और नियंत्रण के प्रदर्शन को गति देने का कोई और तरीका है?

सधन्यवाद, मैगनस

संपादित करें: कोई डेटा अवगत घटकों रहे हैं या किसी घटनाओं जीयूआई में शुरू हो गया। मैं केवल नियंत्रण बना रहा हूं और उन्हें प्रदर्शित कर रहा हूं। टाइमर का उपयोग करके मैंने समय लेने वाले भाग के रूप में नियंत्रण माता-पिता (AControl.Parent: = AOwner) के असाइनमेंट की पहचान की है।

संपादित करें 2: जैसा कि नीचे की समस्या में दिखाया गया है, गति समस्या माता-पिता को सेट नहीं कर रही है बल्कि नियंत्रण की पेंटिंग है। जब मैंने उस समय का परीक्षण किया जब कंटेनर दिखाई दे रहा था और माता-पिता को नियंत्रण की तत्काल पेंटिंग की वजह से स्थापित किया गया था।

संपादित करें 3: हमारे गतिशील जीयूआई का एक और समय उपभोग करने वाला हिस्सा comboboxes को आइटम असाइन कर रहा है। ComboBox.Items.Assign (DataItems) जहां DataItems में तीन से छह आइटम नहीं हैं।

मेरी मदद करने में समय लेने के लिए सभी को धन्यवाद!

उत्तर

5

नियंत्रण बनाने के लिए या सामान्य रूप से वीसीएल के साथ काम करने के लिए एकाधिक धागे का उपयोग करने की कोशिश न करें। यह वैसे भी गति में सुधार नहीं करेगा, लेकिन वीसीएल के साथ एक महत्वपूर्ण नो-नो है।

संपादित करें: में किया जाना VCL थ्रेड-सुरक्षित नहीं है, नियंत्रण करने के लिए सभी का उपयोग कर सकते है: आप अन्य प्रश्न और StackOverflow पर यहाँ जवाब है कि VCL और एक से अधिक थ्रेड के साथ सौदा है, लेकिन संक्षेप में पढ़ना चाहिए मुख्य धागे का संदर्भ। तो जब कई धागे का उपयोग करते हैं तो आपको लगभग सिंक्रनाइज़() कॉल में लगभग सबकुछ लपेटना होगा, जो वास्तव में सभी धागे को क्रमबद्ध करेगा और चीजों को धीमा कर देगा।

आपकी सबसे अच्छी शर्त आपके यूआई को पुन: स्थापित करना है ताकि इसे सभी को एक साथ बनाया जाना आवश्यक न हो। मांग पर सभी फ्रेम बनाएं, केवल तभी जब उन्हें पहली बार दिखाया जाए।

संपादित करें 2: यह दिखाने के लिए यहां कुछ टेस्ट कोड है कि मूल संपत्ति सेटिंग वास्तविक समस्या नहीं है, लेकिन सभी नियंत्रण (सभी संदेश हैंडलिंग के साथ) संभवतः बनाना है।

procedure TForm1.Button1Click(Sender: TObject); 
var 
    i, j, x, y: integer; 
    Edit: TEdit; 
    Ticks: LongWord; 
begin 
    Visible := FALSE; 
    DestroyHandle; 

    try 
    for i := 1 to 20 do begin 
     y := 20 + i * 25; 
     for j := 1 to 10 do begin 
     x := (j - 1) * 100; 

     Edit := TEdit.Create(Self); 
     Edit.SetBounds(x, y, 98, 23); 
     Edit.Parent := Self; 
     end; 
    end; 
    finally 
    Ticks := timeGetTime; 
    Visible := TRUE; 
    Caption := IntToStr(timeGetTime - Ticks); 
    end; 
end; 

कोड गतिशील रूप से 200 TEdit नियंत्रण बनाता है, माता पिता के फार्म की संभाल को मुक्त कराने के बाद। उन सभी नियंत्रणों को बनाना और उनकी संपत्तियों को सेट करना मेरे सिस्टम पर कुछ 10 मिलीसेकंड लेता है, लेकिन आखिरकार फॉर्म (जो सभी विंडोज़ बनाएगा) दिखाता है, कुछ 100 मिलीसेकंड लेता है। चूंकि यह केवल मुख्य धागे में किया जा सकता है, मुझे संदेह है कि एकाधिक धागे का उपयोग करने से आपकी मदद मिलेगी।

+0

एकाधिक धागे का उद्देश्य उपयोगकर्ता को अन्य भागों (फ्रेम) में लोड होने पर उपयोगकर्ता इंटरफ़ेस के एक हिस्से में काम करना जारी रखना होगा। मैं समझता हूं कि यह तेज़ नहीं हो सकता है लेकिन कम से कम उपयोगकर्ता को इसे खत्म करने की प्रतीक्षा नहीं करनी पड़ेगी। –

+0

धन्यवाद, मैं अब के लिए थ्रेडिंग छोड़ दूंगा, हालांकि यह अभी भी मेरे लिए एक अच्छा विचार है। :-) –

2

मुझे नहीं पता कि यह काम करेगा या नहीं, लेकिन आपने अपने फॉर्म को .dfm टेक्स्ट प्रारूप के रूप में बनाने का प्रयास किया है और फिर ऑब्जेक्टटेक्स्ट टोबिनरी फ़ंक्शन का उपयोग करके .dfm को सीधे फॉर्म में लोड किया है। जांच के लायक यह काम कर सकता है या नहीं भी।

+0

दिलचस्प विचार, लेकिन ऐसा लगता है कि इस तरह के एक साधारण कार्य के लिए जाने का एक लंबा सफर तय है। सृजन समस्या नहीं है लेकिन नियंत्रण की पेंटिंग/संरेखण और मुझे लगता है कि यह एक ही तरीके से काम करेगा चाहे फ्रेम बाइनरी स्ट्रीम से बनाया गया हो या नहीं। लेकिन मैं कोशिश कर सकता हूँ। –

+0

@ मैग्नस: आपको वास्तव में कोशिश करनी चाहिए, प्रक्रिया से निर्णय लेना TWINControl.InsertControl() कार्यान्वयन सीएस रीडिंग सक्रिय होने पर बहुत सी चीजें बस छोड़ दी जाती हैं। यह आगे बढ़ने का आपका सबसे अच्छा तरीका हो सकता है। – mghie

1

आप पृष्ठभूमि थ्रेड में डेटा की वास्तविक पुनर्प्राप्ति ऑफ़लोड कर सकते हैं, लेकिन UI थ्रेड एक थ्रेड, मुख्य थ्रेड में होना चाहिए। तो आपके फ्रेम का वास्तविक सेटअप उसी धागे में होगा।

क्या आपने एक प्रोफाइलर की कोशिश की है? यह हो सकता है कि आपका जीयूआई बहुत जुड़ा हुआ हो, और एक अपडेट/वायर-अप बहुत अनावश्यक घटनाओं/साइड इफेक्ट्स का कारण बनता है। एक प्रोफाइलर का उपयोग करके आप वास्तव में कम प्रदर्शन का कारण बनने में अधिक अंतर्दृष्टि प्राप्त कर सकते हैं। उदाहरण के लिए यह सिग्नल हो सकता है कि आपने डीबी को वापस आने की प्रतीक्षा करने में काफी समय बिताया है या यह हो सकता है कि प्रत्येक सेट एक ऐसी घटना को ट्रिगर करे जो एक और घटना को ट्रिगर करे।

1

यदि आप डेटावेयर नियंत्रण का उपयोग करते हैं, तो सुनिश्चित करें कि आप TDataSet पर DisableControls को कॉल करते हैं। इससे कई पश्चाताप भी हो सकते हैं।

0

बस एक जंगली अनुमान: शायद यह नियंत्रण माता-पिता को रिवर्स पदानुक्रमित क्रम में सेट करने में मदद करता है, यानी पहले सबसे गहरे घोंसले वाले नियंत्रणों के माता-पिता को सेट करें, फिर उनके माता-पिता और इसी तरह। कुछ अनावश्यक रीफ्रेश काट सकता है क्योंकि विंडोज अभी तक आपके नियंत्रणों के बारे में "नहीं जानता" है।

+0

धन्यवाद, मैंने कोशिश की लेकिन एक ही परिणाम। –

2

आप DisableAlign पर क्या सेट कर रहे हैं? बाल नियंत्रण (जैसे पैनल) को पकड़ने वाले प्रत्येक नियंत्रण पर अक्षम करने योग्य प्रयास करने का प्रयास करें। मैंने DisableAlign परिणाम को पहले गतिशील रूप से निर्मित रूपों के लिए एक विशाल गति में देखा है।

संपादित करें: इस बारे में सोचकर, मेरा जवाब आंशिक रूप से सट्टा था। मुझे नहीं पता कि नियंत्रण के पेड़ की जड़ पर DisableAlign सेट करने का प्रभाव उसके बच्चों पर या नहीं होगा। मैंने माना कि यह नहीं करता है, लेकिन शायद यह करता है। मुझे वीसीएल कोड देखना होगा। (गति के बारे में हिस्सा हालांकि सच था।)

+0

धन्यवाद, मैं केवल फ्रेम को ही अक्षम कर रहा था। –

1

एक और जंगली अनुमान: दृश्यमान के साथ अपना कंटेनर (फॉर्म, पैनल या फ्रेम) बनाने का प्रयास करें: = झूठी। फिर उस पर सभी गतिशील रूप से बनाए गए नियंत्रण संलग्न करें, फिर दृश्यमान सेट करें: = सत्य

+0

धन्यवाद मैंने यह कोशिश की है। –

2

मुझे कुछ समय पहले यह समस्या मिली और केवल 'अस्थायी' फ्रेम के भीतर नियंत्रणों को होस्ट करके निर्माण समय में उल्लेखनीय सुधार हुआ (यानी जिसे एक असाइन नहीं किया गया है एक परचा)। मेरा मानना ​​है कि डाउनबाउंड, सेटविज़िबल इत्यादि जैसी कई कॉलों के लिए पैरेंट फॉर्म (आखिरकार) के साथ संवाद करने वाले प्रत्येक नियंत्रण में धीमापन एक फ्लोटिंग फ्रेम का उपयोग करके आप इसे प्राप्त कर सकते हैं और फॉर्म के साथ फ्रेम असाइन कर सकते हैं कि आपको आवश्यकता है

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