2014-09-18 8 views
9

एक और प्रश्न से this answer पढ़ते समय मुझे 100% यकीन था कि निम्न कोड यूआई को लॉक करेगा और कोई भी आंदोलन नहीं करेगा।मेरा फॉर्म क्यों लॉक नहीं है?

private void button1_Click(object sender, EventArgs e) 
{ 
    for (int i = 0; i < 5; i++) 
    { 
     this.Left += 10; 
     System.Threading.Thread.Sleep(75); 
     this.Left -= 10; 
     System.Threading.Thread.Sleep(75); 
    } 
} 

मैं और टिप्पणियों में कई अन्य लोगों ने कहा कि यह काम नहीं होगा, लेकिन ओ पी जोर देकर कहा कि यह किया है और हम कोशिश करनी चाहिए। मैंने एक नया विनफॉर्म प्रोजेक्ट बनाना शुरू कर दिया, एक बटन जोड़ दिया, फिर उपरोक्त कोड को ईवेंट हैंडलर में क्लिक करने के लिए डाला और फॉर्म वास्तव में हिलाया।

इस विधि द्वारा संदेश पंप को अवरुद्ध होने पर फ़ॉर्म कैसे चल रहा है, ऑनपेंट को फ़ॉर्म पर नहीं बुलाया जाना चाहिए और न ही उसके किसी भी बच्चे के नियंत्रण, यह कैसे काम कर रहा है?

+1

एक रूप फायरिंग 'Paint' के बिना भी जा सकते हैं। यह अभी भी एक बुरा विचार है। – SLaks

+0

@SLaks मैं यह नहीं कह रहा हूं कि यह एक अच्छा विचार है, मैं सिर्फ यह जानना चाहता हूं कि बिल्ली क्या चल रहा है, यह काम करता है। –

+2

कुछ कहीं संभावना है 'DoEvents' या कुछ नैतिक समकक्ष। – Servy

उत्तर

10

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

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

XP पर या एरो बंद होने की कोशिश न करें।

+0

जब आप कहते हैं 'और इसे भी प्रभावित करता है' मुझे लगता है कि आप एक शब्द खो रहे हैं, लेकिन मुझे नहीं पता कि यह शब्द क्या है। – Servy

+0

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

1

यह Coroutines और Fibers की वजह से संभव है।

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

जाहिर है वहाँ कहीं अधिक कवर की तुलना में हम जब हम उन प्रतीत होता है अहानिकर गुण this.Left और this.Right सेट की कल्पना की है | के तहत हो रहा है।

और हम यह देख सकते हैं, अगर हम प्रश्न से कोड उदाहरण में थोड़ा लॉगिंग जोड़ते हैं। इसके अलावा — क्योंकि मैंने नीचे दिए गए उदाहरण में Thread.Sleep(75) कॉल को हटा दिया है, और पहले बिंदु — पर एक लंबी नींद जोड़ दी है, हम देख सकते हैं कि यह उन नींद नहीं है जो अन्य फ़ंक्शन को उपज लाते हैं, लेकिन this.Left और this.Right पर कॉल (जो, इसके अलावा, अभी भी नींद के बिना प्रपत्र हिला):

protected override void WndProc(ref Message m) 
    { 
     if (_logWndProc) 
      listBox1.Items.Add(string.Format("WndProc on thread {0}", Thread.CurrentThread.ManagedThreadId)); 

     base.WndProc(ref m); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     listBox1.Items.Clear(); 
     _logWndProc = true; 
     Thread.Sleep(2000); 
     listBox1.Items.Add(string.Format("After sleep on thread {0} (see any WndProc logs before this line?!!!)", Thread.CurrentThread.ManagedThreadId)); 

     for (int i = 0; i < 5; i++) 
     { 
      listBox1.Items.Add(string.Format("Right {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId)); 
      this.Left += 10; 
      listBox1.Items.Add(string.Format("Left {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId)); 
      this.Left -= 10; 
     } 

     _logWndProc = false; 
    } 

    private bool _logWndProc = false; 

लॉग:

enter image description here

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