C# में कार्य कतारों का परिचय
आधुनिक मल्टीथ्रेडेड प्रोग्रामिंग में, कार्य कतार (task queue) एसिंक्रोनस डेटा प्रोसेसिंग को व्यवस्थित करने के लिए एक मौलिक पैटर्न है। C# (.NET) में, यह पैटर्न कई शक्तिशाली तंत्रों के माध्यम से लागू किया जाता है जो डेवलपर्स को निष्पादन थ्रेड्स को कुशलतापूर्वक प्रबंधित करने और लोड वितरित करने की अनुमति देते हैं।
कार्य कतार क्लासिक producer-consumer (उत्पादक-उपभोक्ता) समस्या को हल करती है, जहां कोड का एक भाग कार्य बनाता है और दूसरा उन्हें संसाधित करता है। इस लेख में, हम C# में कार्य कतारों को लागू करने के मुख्य तरीकों पर विचार करेंगे: सरल संग्रह से लेकर आधुनिक चैनलों (Channel) तक।
कार्य कतारों को लागू करने के मुख्य दृष्टिकोण
1. ConcurrentQueue — थ्रेड-सुरक्षित कतार
सबसे सरल और निम्न-स्तरीय कार्यान्वयन ConcurrentQueue<T> है जो System.Collections.Concurrent नेमस्पेस से आता है। यह थ्रेड-सुरक्षित विधियाँ Enqueue और TryDequeue प्रदान करता है।
using System;using System.Collections.Concurrent;using System.Threading.Tasks;
public class SimpleTaskQueue{ private readonly ConcurrentQueue<Action> _tasks = new(); private readonly Task _worker;
public SimpleTaskQueue() { _worker = Task.Run(ProcessTasks); }
public void Enqueue(Action task) { _tasks.Enqueue(task); }
private void ProcessTasks() { while (true) { if (_tasks.TryDequeue(out var task)) { task(); } } }}लाभ:
- उपयोग में सरलता
- कम मेमोरी खपत
- बिना लॉक के थ्रेड-सुरक्षा
नुकसान:
- लूप में सक्रिय प्रतीक्षा (busy waiting)
- नए कार्यों के बारे में संकेत का अभाव
- रोकने में कठिनाई
2. BlockingCollection — ब्लॉकिंग के साथ कतार
BlockingCollection<T> सक्रिय प्रतीक्षा की समस्या को हल करता है। यह Add और Take विधियाँ प्रदान करता है, जो डेटा उपलब्ध होने तक थ्रेड को ब्लॉक करती हैं।
using System;using System.Collections.Concurrent;using System.Threading.Tasks;
public class BlockingTaskQueue : IDisposable{ private readonly BlockingCollection<Action> _tasks = new(new ConcurrentQueue<Action>()); private readonly Task[] _workers; private bool _disposed;
public BlockingTaskQueue(int workerCount = 4) { _workers = new Task[workerCount]; for (int i = 0; i < workerCount; i++) { _workers[i] = Task.Run(ProcessTasks); } }
public void Enqueue(Action task) { _tasks.Add(task); }
private void ProcessTasks() { foreach (var task in _tasks.GetConsumingEnumerable()) { if (_disposed) break; task(); } }
public void CompleteAdding() { _tasks.CompleteAdding(); }
public void Dispose() { _disposed = true; _tasks.CompleteAdding(); Task.WaitAll(_workers); _tasks.Dispose(); }}मुख्य विशेषताएँ:
- कार्यों के अभाव में थ्रेड का स्वचालित ब्लॉक होना
CancellationTokenके माध्यम से रद्दीकरण का समर्थन- कतार की क्षमता को सीमित करने की संभावना
CompleteAddingके माध्यम से सुरक्षित समाप्ति
आधुनिक दृष्टिकोण: Channel<T>
.NET Core 3.0 और .NET 5 से शुरू करते हुए, C# में System.Threading.Channels.Channel<T> आया — यह कार्य कतार का सबसे अधिक प्रदर्शनकारी और लचीला कार्यान्वयन है। यह एसिंक्रोनस संचालन, रद्दीकरण और थ्रूपुट सीमा का समर्थन करता है।