C# में कार्य कतारों के साथ कार्य करना: एक व्यावहारिक मार्गदर्शिका

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

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

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

परिचय: C# में कार्य कतारों की आवश्यकता क्यों है?

\n

C# (.NET) में आधुनिक विकास में, अक्सर डेटा की एसिंक्रोनस प्रोसेसिंग को व्यवस्थित करने की आवश्यकता उत्पन्न होती है। एक क्लासिक उदाहरण एक वेब सर्वर है जो अनुरोध प्राप्त करता है और मुख्य थ्रेड को ब्लॉक किए बिना उन्हें पृष्ठभूमि में संसाधित करना चाहिए। या एक एप्लिकेशन जो इंटरनेट से फ़ाइलें डाउनलोड करता है और पहले से डाउनलोड की गई फ़ाइलों को समानांतर में संसाधित करता है। ऐसे परिदृश्यों के लिए, «Producer-Consumer» (उत्पादक-उपभोक्ता) पैटर्न आदर्श है, और इसका आधार कार्य कतार है।

\n

कार्य कतार एक थ्रेड (या एसिंक्रोनस ऑपरेशन) से दूसरे में कार्य को सुरक्षित रूप से स्थानांतरित करने की अनुमति देती है, सामान्य डेटा तक पहुंच को सिंक्रोनाइज़ करती है। इस लेख में, हम C# में कतारों को लागू करने के तीन मुख्य तरीकों पर चर्चा करेंगे: ConcurrentQueue, BlockingCollection और आधुनिक System.Threading.Channels। इनमें से प्रत्येक विभिन्न परिदृश्यों के लिए उपयुक्त है, और हम उन्हें व्यावहारिक उदाहरणों के साथ समझेंगे।

\n\n

1. ConcurrentQueue — बुनियादी थ्रेड-सुरक्षित कतार

\n

ConcurrentQueue<T> नेमस्पेस System.Collections.Concurrent से सबसे सरल थ्रेड-सुरक्षित कतार है। यह उच्च प्रदर्शन सुनिश्चित करने के लिए lock-free एल्गोरिदम (तुलना और अदला-बदली, CAS) का उपयोग करता है। हालांकि, जब कतार खाली होती है तो यह थ्रेड को ब्लॉक नहीं करता है — आपको स्वयं प्रतीक्षा को लागू करना होगा।

\n\n

उदाहरण: कई स्रोतों से डेटा लोड करना

\n

मान लीजिए, हमारे पास एक कार्य है: 10 वेब पेज डाउनलोड करना और उन्हें संसाधित करना। एक थ्रेड (Producer) कतार में URL जोड़ता है, और कई थ्रेड (Consumers) उन्हें लेते हैं और डाउनलोड करते हैं।

\n
using System;\nusing System.Collections.Concurrent;\nusing System.Threading.Tasks;\n\npublic class ConcurrentQueueExample\n{\n    public static async Task RunAsync()\n    {\n        var queue = new ConcurrentQueue<string>();\n        var urls = new[] { "https://example.com", "https://dotnet.microsoft.com" };\n\n        // Producer: कार्य जोड़ना\n        foreach (var url in urls)\n        {\n            queue.Enqueue(url);\n        }\n\n        // Consumers: कार्यों को संसाधित करना\n        var tasks = new Task[3];\n        for (int i = 0; i < tasks.Length; i++)\n        {\n            tasks[i] = Task.Run(() =>\n            {\n                while (queue.TryDequeue(out var url))\n                {\n                    Console.WriteLine($"प्रसंस्करण: {url}");\n                    // कार्य का अनुकरण\n                    Task.Delay(500).Wait();\n                }\n            });\n        }\n\n        await Task.WhenAll(tasks);\n        Console.WriteLine("सभी कार्य पूर्ण हो गए।");\n    }\n}
\n

लाभ: सरलता, बड़ी संख्या में संचालन पर उच्च प्रदर्शन।
\nनुकसान: प्रतीक्षा का कोई अंतर्निहित तंत्र नहीं (जांच के साथ लूप की आवश्यकता), कतार के आकार को सीमित करना कठिन।

\n\n

2. BlockingCollection — ब्लॉकिंग और सीमा के साथ कतार

\n

BlockingCollection<T> एक थ्रेड-सुरक्षित संग्रह के ऊपर एक रैपर है, जो उपभोक्ता थ्रेड को तब ब्लॉक करने की क्षमता जोड़ता है जब कतार खाली होती है, और उत्पादक थ्रेड को तब ब्लॉक करता है जब कतार भरी होती है। डिफ़ॉल्ट रूप से, यह ConcurrentQueue का उपयोग करता है, लेकिन IProducerConsumerCollection<T> को लागू करने वाले किसी भी संग्रह को प्रतिस्थापित किया जा सकता है।

\n\n

उदाहरण: बफर सीमा के साथ ऑर्डर प्रसंस्करण

\n

एक ऑर्डर प्रसंस्करण प्रणाली की कल्पना करें। उत्पादक ऑर्डर उत्पन्न करता है, और तीन उपभोक्ता उन्हें संसाधित करते हैं। बफर 10 तत्वों तक सीमित है ताकि बहुत अधिक मेमोरी की खपत न हो।

\n
using System;\nusing System.Collections.Concurrent;\nusing System.Threading.Tasks;\n\npublic class BlockingCollectionExample\n{\n    public static async Task RunAsync()\n    {\n        using var orders = new BlockingCollection<string>(boundedCapacity: 10);\n\n        // Producer\n        var producer = Task.Run(() =>\n        {\n            for (int i = 1; i <= 20; i++)\n                

ब्लॉग

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