मैं बहुभाषी से संबंधित कई प्रश्नों का उत्तर देता हूं और मैं अक्सर विभिन्न तरीकों से पूछे जाने वाले एक ही मूल प्रश्न को देखता हूं। मैं सबसे आम समस्याओं को प्रस्तुत करूंगा जैसा कि मैंने उन्हें वर्षों में देखा है और समझाया है कि नई प्रौद्योगिकियों ने इन समस्याओं को कैसे हल किया है।
पाश चर
इस से अधिक बंद करने पर एक समस्या सूत्रण के लिए विशिष्ट नहीं है, लेकिन सूत्रण के उपयोग निश्चित रूप से समस्या आवर्धित करता है। सी # 5.0 प्रत्येक पुनरावृत्ति के लिए एक नया चर बनाकर foreach
लूप के लिए इस समस्या को हल करता है। अब आपको लैम्ब्डा अभिव्यक्ति बंद करने के लिए एक विशेष चर बनाने की आवश्यकता नहीं होगी। दुर्भाग्यवश, for
लूप को अभी भी एक विशेष कैप्चरिंग चर के साथ संभालने की आवश्यकता होगी।
अतुल्यकालिक कार्यों
.NET 4.0 पूर्ण होने की प्रतीक्षा CountdownEvent
वर्ग जो तर्क कई कार्यों को पूरा करने के लिए प्रतीक्षा करने के लिए आवश्यक का एक बहुत समाहित की शुरुआत की। अधिकांश जूनियर डेवलपर्स Thread.Join
कॉल या एक WaitHandle.WaitAll
कॉल का उपयोग करते थे। इनमें से दोनों में स्केलेबिलिटी समस्याएं हैं। पुराना पैटर्न एक ManualResetEvent
का उपयोग करना था और जब काउंटर शून्य तक पहुंच गया तो इसे सिग्नल करें। काउंटर को Interlocked
कक्षा का उपयोग करके अपडेट किया गया था। CountdownEvent
इस पैटर्न को बहुत आसान बनाता है। बस अपने मुख्य को एक कार्यकर्ता के रूप में पेश करना याद रखें, साथ ही उस सूक्ष्म दौड़ की स्थिति से बचने के लिए जो तब हो सकता है जब सभी कार्यकर्ताओं के कतार में एक कार्यकर्ता समाप्त हो जाए।
.NET 4.0 ने Task
कक्षा भी पेश की जिसमें बच्चे के कार्यों को TaskCreationOptions.AttachedToParent
के माध्यम से बंद कर दिया जा सकता है। यदि आप माता-पिता पर Task.Wait
पर कॉल करते हैं तो यह सभी बाल कार्यों को पूरा करने की प्रतीक्षा करेगा।
निर्माता-उपभोक्त
.NET 4.0 BlockingCollection
वर्ग जो छोड़कर जब संग्रह खाली है यह ब्लॉक कर सकते हैं कि एक सामान्य कतार की तरह काम करता शुरुआत की। आप Add
पर कॉल करके किसी ऑब्जेक्ट को कतारबद्ध कर सकते हैं और Take
पर कॉल करके ऑब्जेक्ट को हटा सकते हैं। Take
ब्लॉक जब तक कोई आइटम उपलब्ध न हो। यह निर्माता-उपभोक्ता तर्क को काफी सरल बनाता है। यह मामला होता था कि डेवलपर्स अपनी खुद की अवरुद्ध कतार कक्षा लिखने की कोशिश कर रहे थे। लेकिन, अगर आपको नहीं पता कि आप क्या कर रहे हैं तो आप वास्तव में इसे खराब कर सकते हैं ... बुरा। वास्तव में, सबसे लंबे समय तक माइक्रोसॉफ्ट के पास एमएसडीएन दस्तावेज में एक अवरुद्ध कतार उदाहरण था जो स्वयं बुरी तरह टूट गया था। सौभाग्य से, इसे हटा दिया गया है।
कार्यकर्ता धागा प्रगति
साथ अद्यतन कर रहा है यूआई BackgroundWorker
की शुरूआत एक WinForm आवेदन नौसिखिया डेवलपर्स के लिए बहुत आसान से एक पृष्ठभूमि कार्य का चक्कर बना दिया। मुख्य लाभ यह है कि आप DoWork
ईवेंट हैंडलर से ReportProgress
पर कॉल कर सकते हैं और ProgressChanged
ईवेंट हैंडलर स्वचालित रूप से यूआई थ्रेड पर मार्शल हो जाएंगे। बेशक, कोई भी जो एसओ पर मेरे उत्तरों को ट्रैक करता है जानता है कि सरल प्रगति जानकारी के साथ यूआई को अपडेट करने के लिए समाधान के रूप में मैं मार्शलिंग ऑपरेशंस (या इसी तरह) के बारे में कैसा महसूस करता हूं। मैं हर समय इसे चीरता हूं क्योंकि यह आम तौर पर एक भयानक दृष्टिकोण है। BackgroundWorker
अभी भी डेवलपर को पुश मॉडल (पृष्ठभूमि में मार्शलिंग ऑपरेशंस के माध्यम से) में मजबूर करता है, लेकिन कम से कम यह दृश्यों के पीछे यह सब करता है।
आह्वान
की असजीलाता हम सभी जानते हैं कि एक यूआई तत्व केवल यूआई धागे से पहुँचा जा सकता है। इसका आम तौर पर मतलब था कि डेवलपर को यूआई थ्रेड पर नियंत्रण स्थानांतरित करने के लिए ISynchronizeInvoke
, DispatcherObject
, या SynchronizationContext
के माध्यम से मार्शलिंग ऑपरेशंस का उपयोग करना था। लेकिन इसका सामना करते हैं। ये मार्शलिंग ऑपरेशन बदसूरत लगते हैं। Task.ContinueWith
ने इसे थोड़ा और सुरुचिपूर्ण बनाया, लेकिन सी # 5 के नए एसिंक्रोनस प्रोग्रामिंग मॉडल के हिस्से के रूप में असली महिमा await
पर जाती है। await
का उपयोग Task
के लिए इस तरह से पूरा करने के लिए किया जा सकता है कि कार्य नियंत्रण चलने पर प्रवाह नियंत्रण अस्थायी रूप से बाधित हो और फिर सही सिंक्रनाइज़ेशन संदर्भ में उस स्थान पर लौटा दिया जाए। उन सभी Invoke
कॉल के प्रतिस्थापन के रूप में await
का उपयोग करने से कहीं अधिक सुरुचिपूर्ण और संतोषजनक नहीं है।
समानांतर प्रोग्रामिंग
मैं अक्सर सवाल पूछ कैसे चीजें समानांतर में हो सकता है देखते हैं। पुराना तरीका कुछ धागे बनाना था या ThreadPool
का उपयोग करना था। .NET 4.0 ने टीपीएल और पिनिंगक का उपयोग किया। Parallel
कक्षा समानांतर में जाने वाले लूप के पुनरावृत्तियों को प्राप्त करने का एक शानदार तरीका है। और PLINQ के AsParallel
सादे पुराने LINQ के लिए एक ही सिक्के का एक अलग पक्ष है। ये नई टीपीएल विशेषताएं मल्टीथ्रेड प्रोग्रामिंग की इस श्रेणी को बहुत सरल बनाती हैं।
.NET 4.5 टीपीएल डेटा फ्लो लाइब्रेरी पेश करता है। यह अन्यथा जटिल समानांतर प्रोग्रामिंग समस्या सुरुचिपूर्ण बनाने का इरादा है। यह वर्गों में कक्षाओं को सार तत्व बनाता है। वे लक्ष्य ब्लॉक या स्रोत ब्लॉक हो सकते हैं। डेटा एक ब्लॉक से दूसरे ब्लॉक में बह सकता है। BufferBlock<T>
, BroadcastBlock<T>
, ActionBlock<T>
, आदि सहित कई अलग-अलग ब्लॉक हैं जो सभी अलग-अलग चीजें करते हैं। और, ज़ाहिर है, पूरी लाइब्रेरी को नए async
और await
कीवर्ड के उपयोग के लिए अनुकूलित किया जाएगा। यह कक्षाओं का एक रोमांचक नया सेट है जो मुझे लगता है कि धीरे-धीरे पकड़ जाएगा।
सुंदर समाप्ति
कैसे आप एक धागा बंद करने के लिए मिलता है? मैं यह सवाल बहुत देखता हूं। सबसे आसान तरीका Thread.Abort
पर कॉल करना है, लेकिन हम सभी इसे करने के खतरे को जानते हैं ... मुझे उम्मीद है। इसे सुरक्षित तरीके से करने के कई तरीके हैं। .NET 4.0 ने CancellationToken
और CancellationTokenSource
के माध्यम से रद्दीकरण नामक एक और एकीकृत अवधारणा पेश की। पृष्ठभूमि कार्य IsCancellationRequested
पर मतदान कर सकते हैं या सुरक्षित बिंदुओं पर केवल ThrowIfCancellationRequested
पर कॉल कर सकते हैं ताकि वे जो भी काम कर रहे हों, उसमें सावधानी से बाधा डालें। रद्दीकरण का अनुरोध करने के लिए अन्य धागे Cancel
पर कॉल कर सकते हैं।
प्रतिनिधि और घटनाओं के पास थ्रेडिंग के साथ कुछ लेना देना नहीं है, और वे .NET 4.5 के लिए विशिष्ट नहीं हैं। कृपया अधिक स्पष्ट रहें, क्योंकि मैं यह नहीं बता सकता कि आप किस बारे में बात कर रहे हैं। –
@ जॉन सैंडर्स असिनक प्रतिनिधि थ्रेडिंग को आसान बनाते हैं; http://msdn.microsoft.com/en-us/library/22t547yb.aspx – LamonteCristo
क्या आपने देखा है कि प्रतिनिधियों का असीमित उपयोग संस्करण 1.0 के बाद .NET में रहा है? –