2010-03-25 24 views
7

लोड करने में तेज़ गति कैसे करें I WinForms ऐप के स्टार्टअप को अनुकूलित कर रहा हूं। एक मुद्दा जिसे मैंने पहचाना है वह स्प्लैश स्क्रीन फॉर्म की लोडिंग है। इसमें एक सेकंड में लगभग आधे सेकेंड लगते हैं।स्प्लैश स्क्रीन

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

उत्तर

9

द।विंडोज फॉर्म ऐप में स्प्लैश स्क्रीन के लिए नेट फ्रेमवर्क का पहले से ही बहुत अच्छा समर्थन है। कोड नमूने के लिए this thread देखें। यह वास्तव में गर्म स्टार्टअप समय के लिए अनुकूलित है, यह सुनिश्चित करता है कि स्पलैश थ्रेड और स्क्रीन मुख्य ऐप शुरू करने से पहले चल रही है और चल रही है।

1

हां।

आप एक नया एसटीए धागा कि Application.Run का उपयोग कर स्प्लैश स्क्रीन से पता चलता बनाने की जरूरत है, तो Invoke उपयोग करने के बाद मुख्य रूप के लिए तैयार है (मुख्य थ्रेड पर) Close कहते हैं।

संपादित: उदाहरण के लिए:

static SplashForm splash; 

Thread splashThread = new Thread(delegate() { 
    splash = new SplashForm(); 
    Application.Run(splash);  //Blocking call on separate thread  
}); 
splashThread.SetApartmentState(ApartmentState.STA) 
splashThread.Start(); 

LoadApp(); 

//In MainForm_Shown: 
splash.BeginInvoke(new Action(splash.Close)); 

अनुकूलतम प्रदर्शन के लिए, आप अपने Main विधि स्प्लैश स्क्रीन दिखाने करना चाहिए, फिर एक अलग विधि है कि आवेदन लोड करता है कहते हैं। इस तरह, स्पलैश स्क्रीन दिखाए जाने के बाद सभी असेंबली लोड हो जाएंगी। (जब आप कोई विधि कॉल करते हैं, तो JITter विधि को निष्पादित करने से पहले उपयोग किए जाने वाले सभी प्रकारों को लोड करेगा)

+0

यह एक दिलचस्प दृष्टिकोण है। क्या आप वास्तव में एसटीए थ्रेड बनाने के तरीके पर विस्तार कर सकते हैं। – AngryHacker

+0

धागे को फैलाना काउंटर-उत्पादक है। लक्ष्य स्प्लैश स्क्रीन दिखाने के लिए जितना समय लगता है, उतना ही कम करना है, तो ऐप लोड प्रक्रिया के साथ अपने चक्र साझा करके इसे धीमा क्यों करें? स्पलैश दिखाने के लिए सबकुछ समर्पित करने के लिए सर्वश्रेष्ठ, फिर बाकी ऐप लोड करें। –

+0

@ चार्ल्स: यदि आप मुख्य धागे पर स्पलैश दिखाते हैं, तो उसे कोई संदेश नहीं मिलेगा और जवाब देना बंद कर देगा। – SLaks

1

WinForms में मल्टीथ्रेडिंग ठीक है जब तक कि सभी यूआई एक थ्रेड पर रहता है।

यह केवल स्प्लैश स्क्रीन आमतौर पर किया जाता है। महत्वपूर्ण काम पृष्ठभूमि थ्रेड पर किया जाता है, जबकि स्पलैश स्क्रीन विंडो यूआई थ्रेड पर दिखाया जाता है ताकि उपयोगकर्ता को यह पता चल सके कि शेष कार्यक्रम जल्द ही दिखाई देगा।

महत्वपूर्ण सामग्री होने के बाद, यूआई थ्रेड को यह बताने के लिए एक कार्यक्रम बढ़ाएं कि स्प्लैश स्क्रीन को छिपाने का समय है (केवल इवेंट हैंडलर को मार्शल करना, Invoke() का उपयोग करके, यूआई थ्रेड पर वापस क्रम में याद रखें स्प्लैश स्क्रीन को बंद करने के लिए)।

3

यदि आपका लक्ष्य स्प्लैश स्क्रीन को जितनी जल्दी हो सके प्राप्त करने के लिए कोई धागा फैलाने से प्राप्त करने के लिए कुछ भी नहीं है।

वहाँ छप स्क्रीन करने के कई तरीके हैं, और एक और अधिक परिष्कृत एक here उल्लेख किया गया है, लेकिन यह एक आसान विधि मैं पूर्ण सफलता के साथ इस्तेमाल किया है है: बस आप लोड और छप रूप को दिखाने सुनिश्चित पहले

, और उसके बाद उपयोगकर्ता अपने ऐप को लोड करना जारी रखता है जबकि उपयोगकर्ता सुंदर स्पलैश स्क्रीन देख रहा है। जब MainForm लोड हो रहा है किया है, यह छप सही बंद करने से पहले वह खुद को दिखाता है (करने के लिए एक आसान तरीका यह अपने निर्माता में MainForm के लिए छप रूप से पारित है):

static void Main() 
{ 
    Application.SetCompatibleTextRenderingDefault(false); 
    SplashForm splash = new SplashForm(); 
    splash.Show(); 
    splash.Refresh(); // make sure the splash draws itself properly 
    Application.EnableVisualStyles(); 
    Application.Run(new MainForm(splash)); 
} 

public partial class MainForm : Form 
{ 
    SplashForm _splash; 
    public MainForm(SplashForm splash) 
    { 
     _splash = splash; 
     InitializeComponent(); 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     base.OnLoad(e); 

     // or do all expensive loading here (or in the constructor if you prefer) 

     _splash.Close(); 
    } 
} 

वैकल्पिक: यदि आप नहीं करना चाहते हैं MainForm (शायद यह असजीला लगता है), तो MainForm के लोड घटना की सदस्यता, और वहाँ स्प्लैश स्क्रीन बंद करने के लिए छप पारित करने के लिए:

static class Program 
{ 
    static SplashForm _splash; 

    [STAThread] 
    static void Main() 
    { 
     Application.SetCompatibleTextRenderingDefault(false); 
     _splash = new SplashForm(); 
     _splash.Show(); 
     _splash.Refresh(); 
     Application.EnableVisualStyles(); 
     MainForm mainForm = new MainForm(); 
     mainForm.Load += new EventHandler(mainForm_Load); 
     Application.Run(mainForm); 
    } 

    static void mainForm_Load(object sender, EventArgs e) 
    { 
     _splash.Dispose(); 
    } 
} 

रूप this thread में उल्लेख किया है, इस समाधान के लिए संभावित नकारात्मक पक्ष यह है कि है उपयोगकर्ता स्प्लैश स्क्रीन से बातचीत करने में सक्षम नहीं होगा। हालांकि, आमतौर पर इसकी आवश्यकता नहीं होती है।

+0

यदि आप मुख्य धागे पर स्पलैश दिखाते हैं, तो यह विंडोज संदेशों को संसाधित करने में सक्षम नहीं होगा और प्रतिक्रिया देना बंद कर देगा। – SLaks

+0

हां, और यह एक मुद्दा हो सकता है यदि ऐप को लोड करने में बहुत लंबा समय लगता है, और डेवलपर चाहता है कि उपयोगकर्ता प्रतीक्षा करते समय स्प्लैश स्क्रीन से बातचीत कर सके। लेकिन एक उचित समय में लोड होने वाले ऐप्स के लिए, स्प्लैश स्क्रीन के साथ बातचीत सामान्य रूप से वांछित नहीं होती है। –

+1

यदि यह थोड़े समय में लोड होता है तो स्प्लैश स्क्रीन का उपयोग करने में थोड़ा सा बिंदु होता है। –

1

उत्तर वास्तव में धारणा के बारे में है। विभिन्न विधियां हैं, एनजीएनएन एक असेंबली, जीएसी में चीजें डाल रही है, लेकिन आपको क्या समझना चाहिए कि वास्तव में क्या चल रहा है।

सी # वर्चुअल मशीन लोड करने के लिए समय की आवश्यकता है, संदर्भित असेंबली लोड करें, और उस स्प्लैश स्क्रीन पर मौजूद असेंबली लोड करें। और फिर पहली स्क्रीन लॉन्च करने के लिए "ठंड" शुरू होने में कुछ समय लगता है।

यह जेआईटी संकलन के कारण है जब आप पहली बार स्क्रीन तक पहुंचते हैं।

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

अन्यथा, एप्लिकेशन पहली बार शुरू होने पर उपयोगकर्ताओं के लिए घबराहट और धीमे दिखाई देते हैं। स्क्रीन की गर्म स्टार्टअप बहुत तेज है क्योंकि असेंबली और जेआईटी समाप्त हो गया है।

1

हम इसे छोटे छोटे देशी सी ++ एप्लिकेशन प्रदान करके करते हैं जो स्पलैश स्क्रीन के रूप में कार्य करता है।

  1. उपयोगकर्ता पर दो बार क्लिक आवेदन आइकन:

    यह तो इस प्रक्रिया इस प्रकार है।

  2. सी ++ ऐप शुरू होता है, जो एक स्पलैश बिटमैप को WS_TOPMOST के रूप में दिखाता है।
  3. सी ++ ऐप मुख्य सी # ऐप लॉन्च करता है।
  4. सी # ऐप शुरू होता है, अंततः सी ++ ऐप (एक साधारण फ़ाइल के माध्यम से) को छोड़ने के लिए सूचित करता है।
  5. सी ++ ऐप छोड़ देता है।

सी ++ एप्लिकेशन में टाइमआउट भी होता है (यदि सी # ऐप क्रैश हो जाता है) और स्वचालित रूप से छोड़ देता है अगर इसे 30 सेकंड के भीतर छोड़ने के लिए अधिसूचित नहीं किया जाता है।

इस दृष्टिकोण में इस तथ्य की कमी है कि आप एप्लिकेशन को टास्क बार में पिन नहीं कर सकते हैं। यदि आप सी ++ ऐप पिन करते हैं (जो अंतिम उपयोगकर्ता के लिए मुख्य ऐप है), तो आपको टास्क बार पर एक और कार्य मिलता है, क्योंकि सी # ऐप अलग है। मुझे लगता है, मैं इसे C++ और C# अनुप्रयोग दोनों के application manifest में सेटिंग प्रदान करके इसे हल कर सकता हूं ताकि उन्हें टास्क बार के संदर्भ में "समान" एप्लिकेशन बनने के लिए निर्देश दिया जा सके।

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