I've reviewed the QueuedTaskScheduler and I'm very confused.
http://blogs.msdn.com/b/pfxteam/archive/2010/04/09/9990424.aspx[
^]
So I wrote this class to do what I wanted.
What I wanted is a class that will queue up tasks in the background and start them in order with a lower priority. Also managing a maximum concurrency.
But also I wanted to allow for the the provided Action/Task to be executed synchronously (or not) when a maximum queue limit is reached.
Can someone tell me how this might be bad or why I should simply use a TaskScheduler?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Utilities
{
public class TaskQueue
{
readonly object _syncRoot = new Object();
readonly Queue<Action> _actions = new Queue<Action>();
readonly List<Thread> _tasks = new List<Thread>();
int _maxConcurrency;
public int MaxConcurrency
{
get
{
return _maxConcurrency;
}
set
{
Contract.Requires(value > 0);
lock (_tasks)
_maxConcurrency = value;
}
}
int _maxTasks;
public int MaxTasks
{
get
{
return _maxTasks;
}
set
{
Contract.Requires(value > 0);
lock (_tasks)
_maxTasks = value;
}
}
public int Count {
get {
return _tasks.Count + _actions.Count;
}
}
public TaskQueue(int maxConcurrency = 4, int maxTasks = 24)
{
MaxConcurrency = maxConcurrency;
MaxTasks = Math.Max(maxConcurrency,maxTasks);
}
void Cycle()
{
if (_tasks.Count < _maxConcurrency)
{
lock (_syncRoot)
{
if (_tasks.Count < _maxConcurrency && _actions.Any())
{
var task = new Thread(new ThreadStart(_actions.Dequeue()));
_tasks.Add(task);
task.IsBackground = true;
task.Priority = ThreadPriority.Lowest;
Task.Factory.StartNew(() =>
{
task.Start();
task.Join();
lock (_syncRoot)
_tasks.Remove(task);
Cycle();
});
}
}
}
}
public bool Queue(Action action, bool executeSynchronousIfLimitreached = true)
{
if(Count < MaxTasks) {
lock (_syncRoot)
{
if (Count < MaxTasks)
{
_actions.Enqueue(action);
Cycle();
return true;
}
}
}
Debug.Print("Task limit reached: " + MaxTasks);
if(executeSynchronousIfLimitreached)
action();
return false;
}
}
}