C# में समवर्तीता और मल्टीथ्रेडिंग: उन्नत स्तर

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

C# में समवर्तीता और मल्टीथ्रेडिंग: उन्नत स्तर

\n\n

C# (.NET) में आधुनिक विकास में, समवर्तीता और मल्टीथ्रेडिंग को कुशलतापूर्वक प्रबंधित करने की क्षमता एक अनुभवी इंजीनियर को शुरुआती से अलग करती है। Thread और सरल लॉक के बुनियादी ज्ञान उच्च-प्रदर्शन, उत्तरदायी और स्केलेबल एप्लिकेशन बनाने के लिए अब पर्याप्त नहीं हैं। इस लेख में, हम उन्नत तकनीकों का विश्लेषण करेंगे: async/await की गहरी समझ से लेकर System.Threading.Channels और TPL Dataflow के उपयोग तक। यह सामग्री उन डेवलपर्स के लिए है जो पहले से मल्टीथ्रेडिंग की मूल बातों से परिचित हैं।

\n\n

1. async/await और SynchronizationContext में गहराई से उतरना

\n\n

कई डेवलपर्स async/await का उपयोग करते हैं, लेकिन पूरी तरह से नहीं समझते कि टास्क शेड्यूलर (Task Scheduler) और SynchronizationContext निरंतरताओं (continuations) का प्रबंधन कैसे करते हैं। उन्नत स्तर पर, यह नियंत्रित करना महत्वपूर्ण है कि await के बाद कोड किस थ्रेड में निष्पादित होता है।

\n\n

डिफ़ॉल्ट रूप से, await वर्तमान SynchronizationContext (या TaskScheduler) को कैप्चर करता है। UI एप्लिकेशन (WPF, WinForms) में, यह निष्पादन को मुख्य थ्रेड पर वापस लाता है। ASP.NET Core और कंसोल एप्लिकेशन में, संदर्भ अक्सर अनुपस्थित होता है, और निरंतरता पूल के किसी भी थ्रेड पर निष्पादित हो सकती है।

\n\n

बारीक ट्यूनिंग के लिए ConfigureAwait(false) का उपयोग करें। यह रनटाइम को मूल संदर्भ में वापस जाने का प्रयास न करने का निर्देश देता है, जो प्रदर्शन को बढ़ाता है और लाइब्रेरी कोड में डेडलॉक (deadlocks) को रोकता है।

\n\n
public async Task<string> FetchDataAsync(HttpClient client)\n{\n    // निरंतरता संदर्भ को कैप्चर नहीं करेगी\n    var result = await client.GetStringAsync("https://api.example.com")\n                              .ConfigureAwait(false);\n    // यह कोड पूल के किसी भी थ्रेड पर निष्पादित होगा\n    return ProcessResult(result);\n}\n\npublic async Task<string> FetchDataWithContextAsync(HttpClient client)\n{\n    // निरंतरता मूल संदर्भ में वापस आएगी (उदाहरण के लिए, UI थ्रेड)\n    var result = await client.GetStringAsync("https://api.example.com");\n    // यह कोड गारंटी के साथ मूल संदर्भ में निष्पादित होगा\n    return ProcessResult(result);\n}
\n\n

उन्नत सलाह: गैर-मानक परिदृश्यों के लिए अपना स्वयं का SynchronizationContext बनाएं, उदाहरण के लिए, थ्रेड्स की एक निश्चित संख्या के साथ कार्यों की एक कतार व्यवस्थित करने के लिए।

\n\n

2. Task Parallel Library (TPL) और डेटा समानांतरता

\n\n

TPL समानांतरता के लिए उच्च-स्तरीय एब्स्ट्रैक्शन प्रदान करता है। Parallel.For और Parallel.ForEach स्वचालित रूप से संग्रह को भागों (chunks) में विभाजित करते हैं और उन्हें थ्रेड्स में वितरित करते हैं। हालांकि, उन्नत स्तर पर, यह समझना आवश्यक है कि समानांतरता की डिग्री और अपवाद हैंडलिंग को कैसे कॉन्फ़िगर किया जाए।

\n\n

थ्रेड्स की संख्या को सीमित करने के लिए ParallelOptions का उपयोग करें, साथ ही लूप से जल्दी बाहर निकलने के लिए ParallelLoopState का उपयोग करें।

\n\n
var options = new ParallelOptions\n{\n    MaxDegreeOfParallelism = Environment.ProcessorCount / 2 // आधे कोर का उपयोग करें\n};\n\nParallel.ForEach(sourceData, options, (item, state) =>\n{\n    try\n    {\n        // भारी ऑपरेशन\n        ProcessItem(item);\n    }\n    catch (Exception ex)\n    {\n        // लॉग करें और निष्पादन बाधित करें\n        Console.WriteLine($"त्रुटि: {ex.Message}");\n        state.Stop(); // लूप का निष्पादन बाधित करता है\n    }\n});
\n\n

महत्वपूर्ण: Parallel.ForEach प्रसंस्करण के क्रम की गारंटी नहीं देता है। यदि क्रम महत्वपूर्ण है, तो इंडेक्स के साथ Parallel.ForEach या PLINQ (AsParallel().AsOrdered()) का उपयोग करें।

\n\n

3. Producer-Consumer के लिए चैनल (System.Threading.Channels)

\n\n

Channel<T> क्लास .NET Core 3.0 में दिखाई दिया और प्रोड्यूसर-कंज़्यूमर परिदृश्यों के लिए एक शक्तिशाली उपकरण बन गया। यह थ्रेड-सुरक्षित, एसिंक्रोनस और कुशल है। चैनल दो प्रकार के होते हैं

ब्लॉग

पुस्तक अनुशंसाएँ