優先度の高いタスクのためのスペースを確保する必要がない場合は、 Task
andを使用して単純なヘルパー クラスを作成できContinueWith
ます。
public class SimpleWorkQueue
{
private Task _main = null;
public void AddTask(Action task)
{
if (_main == null)
{
_main = new Task(task);
_main.Start();
}
else
{
Action<Task> next = (t) => task();
_main = _main.ContinueWith(next);
}
}
}
優先度の高いタスクが必要な場合は、おそらくより多くのタスクを自分で処理する必要があります。AddTask()
すべての受信タスクが のリストに挿入され、単一のワーカー スレッドがそのリストからタスクを消費するプロデューサー/コンシューマーの例を次に示します。
public class PrioritizedWorkQueue
{
List<Action> _queuedWork;
object _queueLocker;
Thread _workerThread;
public PrioritizedWorkQueue()
{
_queueLocker = new object();
_queuedWork = new List<Action>();
_workerThread = new Thread(LookForWork);
_workerThread.IsBackground = true;
_workerThread.Start();
}
private void LookForWork()
{
while (true)
{
Action work;
lock (_queueLocker)
{
while (!_queuedWork.Any()) { Monitor.Wait(_queueLocker); }
work = _queuedWork.First();
_queuedWork.RemoveAt(0);
}
work();
}
}
public void AddTask(Action task, bool highPriority)
{
lock (_queueLocker)
{
if (highPriority)
{
_queuedWork.Insert(0, task);
}
else
{
_queuedWork.Add(task);
}
Monitor.Pulse(_queueLocker);
}
}
}