2010-02-02 18 views
5

मैं 5 पृष्ठभूमिवर्कर ऑब्जेक्ट्स का उपयोग एक निश्चित उद्देश्य के लिए एक ही समय में चल रहा हूं, और उनमें से सभी को एक ही लेबल बदलना है। मैं उसको कैसे करू?पृष्ठभूमि वर्कर मल्टीथ्रेड एक्सेस

मैं फ़ॉर्म को एक से अधिक धागे से कैसे संशोधित करूं? और यदि मैं सार्वजनिक स्ट्रिंग को बदलना चाहता हूं तो मैं इसे कैसे कर सकता हूं?

उत्तर

17

एक प्रतिनिधि के साथ Control.Invoke का उपयोग करें।

अपनी पृष्ठभूमि कार्यकर्ता धागा में, बजाय

label4.Text = "Hello"; 

कहने का कहना {} के अंदर

label4.Invoke(new Action(() => 
{ 
    label4.Text = "Hello"; 
} 
)); 

सब कुछ नियंत्रण के धागे पर निष्पादित करता है, तो आप अपवाद से बचें।

यह आपको प्रगति की रिपोर्ट करने के बजाय BackgroundWorker से अपने उपयोगकर्ता इंटरफ़ेस में मनमाने ढंग से परिवर्तन करने की अनुमति देता है।

+0

रिपोर्ट प्रोग्रेस आपको यूआई में मनमाने ढंग से बदलाव करने देगा। –

+0

अगर मैं अब अपने फॉर्म की सार्वजनिक स्ट्रिंग में हो रहा हूं तो मैं इसे कैसे आमंत्रित करूं? – Marcelo

+0

@ हेंक: रिपोर्ट प्रोग्रेस केवल बैकवाउंडवर्कर को एक "UserState" ऑब्जेक्ट भेजने की अनुमति देगा, जिसे बाद में UI को अपडेट करने के लिए प्रोग्रेस चेंज इवेंट हैंडलर द्वारा व्याख्या की जानी चाहिए। मैं जो कहने की कोशिश कर रहा था वह यह है कि Invoke() दृष्टिकोण के साथ आप उस विधि के अंदर कोड को सही तरीके से डाल सकते हैं जहां आप पृष्ठभूमिवर्कर को पहली जगह बनाते हैं, जिससे अधिक कुशल और अधिक पठनीय कोड होता है। यह सामान्य सामान्य व्यापार के साथ पाठ्यक्रम का एक डिज़ाइन निर्णय है। – RobC

2

आप अपने BackgroundWorker में ReportProgress विधि का उपयोग कर सकते हैं जहां आप लेबल को बदलना चाहते हैं और ProgressChanged ईवेंट हैंडलर में वास्तविक कोड लिखना चाहते हैं।

+0

समस्या यह है कि यह लेबल दिखाने वाला एक अपवाद है, इसलिए यह हर बार नहीं है कि पृष्ठभूमि कार्यकर्ता द्वारा चलाया गया तरीका – Marcelo

+0

के साथ कोई बातचीत करेगा, आप GUI को जानकारी पोस्ट करने के लिए राययल के सुझाव का उपयोग कर सकते हैं जो अद्यतन स्वयं ही कर सकता है। –

0

this answer पर एक नज़र डालें। इससे कोई फर्क नहीं पड़ता कि आपके पास एक, पांच या हजार कार्यकर्ता धागे हैं (अवधारणा के अर्थ में)।

1

आपको एक gui पर async BeginInvoke की बजाय सिंक्रोनस Invoke को कॉल करने से बहुत सावधान रहना चाहिए। आपके पास जल्द ही एक अनुत्तरदायी और मैला गुई होगा जो खुद को पेंट करने के लिए संघर्ष कर रहा है, साथ ही साथ मृतकों के लिए संभावित भी है।
यह इस बात पर निर्भर करता है कि आप इसे कितनी बार अपडेट करते हैं - और क्या आपके पृष्ठभूमि धागे को वास्तव में गुई लौटने के लिए प्रतीक्षा करने की आवश्यकता है? यह आपके मॉडल के साथ एक समस्या की तरह लगता है।

1

साथ ही Control.BeginInvoke, आप SynchronizationContext पर एक नज़र डाल सकते हैं।

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

सिंक्रनाइज़ेशन कॉन्टेक्स्ट here और here पर दो अच्छे लेख हैं।