العمل مع قوائم المهام في C#: دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة في قوائم المهام في 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> — وهو التنفيذ الأكثر أداءً ومرونة لقائمة المهام. يدعم العمليات غير المتزامنة، والإلغاء، وتحديد معدل النقل.

المدونات

توصيات الكتب