多任务管理类 MutilTaskManager
计算和计算所需的数据能被较为平均的非配到若干task的时候,下面的任务管理类可以提供在大数据大计算量的情况下非精确的控制task的执行数量来限制计算量和内存占用量.
下面是代码(非线程安全版本):
public class MutilTaskManager
{
private readonly int _maxRun;
private readonly int _maxQuenen;
private List<Task> _taskRunningList;
private readonly Queue<Task> _taskQueue;
public bool IsQueueFull
{
get { return _taskQueue.Count > _maxQuenen; }
}
public MutilTaskManager(int maxRun = 8, int maxQuenen = 2)
{
_maxRun = maxRun;
_maxQuenen = maxQuenen;
_taskRunningList = new List<Task>(maxRun);
_taskQueue = new Queue<Task>(2);
}
public void TakeBooting(int sleepTime = 10)
{
if (_taskRunningList.Count >= _maxRun)
{
_taskRunningList = _taskRunningList.Where(it => !it.IsCompleted).ToList();
}
while (_taskRunningList.Count < _maxRun && _taskQueue.Count > 0)
{
var t = _taskQueue.Dequeue();
_taskRunningList.Add(t);
t.Start();
}
System.Threading.Thread.Sleep(sleepTime);
}
public void Enqueue(Task task)
{
_taskQueue.Enqueue(task);
TakeBooting(0);
}
public void WaitAll()
{
while (_taskQueue.Count > 0)
{
TakeBooting();
}
Task.WaitAll(_taskRunningList.ToArray());
}
}
{
private readonly int _maxRun;
private readonly int _maxQuenen;
private List<Task> _taskRunningList;
private readonly Queue<Task> _taskQueue;
public bool IsQueueFull
{
get { return _taskQueue.Count > _maxQuenen; }
}
public MutilTaskManager(int maxRun = 8, int maxQuenen = 2)
{
_maxRun = maxRun;
_maxQuenen = maxQuenen;
_taskRunningList = new List<Task>(maxRun);
_taskQueue = new Queue<Task>(2);
}
public void TakeBooting(int sleepTime = 10)
{
if (_taskRunningList.Count >= _maxRun)
{
_taskRunningList = _taskRunningList.Where(it => !it.IsCompleted).ToList();
}
while (_taskRunningList.Count < _maxRun && _taskQueue.Count > 0)
{
var t = _taskQueue.Dequeue();
_taskRunningList.Add(t);
t.Start();
}
System.Threading.Thread.Sleep(sleepTime);
}
public void Enqueue(Task task)
{
_taskQueue.Enqueue(task);
TakeBooting(0);
}
public void WaitAll()
{
while (_taskQueue.Count > 0)
{
TakeBooting();
}
Task.WaitAll(_taskRunningList.ToArray());
}
}
线程安全版本:
public class MutilTaskManager
{
private readonly int _maxRun;
private readonly int _maxQuenen;
private List<Task> _taskRunningList;
private readonly Queue<Task> _taskQueue;
private object _lockObj = new object();
public bool IsQueueFull
{
get { return _taskQueue.Count > _maxQuenen; }
}
public MutilTaskManager(int maxRun = 8, int maxQuenen = 2)
{
_maxRun = maxRun;
_maxQuenen = maxQuenen;
_taskRunningList = new List<Task>(maxRun);
_taskQueue = new Queue<Task>(2);
}
public void TakeBooting(int sleepTime = 10)
{
lock (_lockObj)
{
if (_taskRunningList.Count >= _maxRun)
{
_taskRunningList = _taskRunningList.Where(it => !it.IsCompleted).ToList();
}
while (_taskRunningList.Count < _maxRun && _taskQueue.Count > 0)
{
var t = _taskQueue.Dequeue();
_taskRunningList.Add(t);
t.Start();
}
}
System.Threading.Thread.Sleep(sleepTime);
}
public void Enqueue(Task task)
{
lock (_lockObj)
{
_taskQueue.Enqueue(task);
}
TakeBooting(0);
}
public void WaitAll()
{
while (_taskQueue.Count > 0)
{
TakeBooting();
}
Task.WaitAll(_taskRunningList.ToArray());
}
}
{
private readonly int _maxRun;
private readonly int _maxQuenen;
private List<Task> _taskRunningList;
private readonly Queue<Task> _taskQueue;
private object _lockObj = new object();
public bool IsQueueFull
{
get { return _taskQueue.Count > _maxQuenen; }
}
public MutilTaskManager(int maxRun = 8, int maxQuenen = 2)
{
_maxRun = maxRun;
_maxQuenen = maxQuenen;
_taskRunningList = new List<Task>(maxRun);
_taskQueue = new Queue<Task>(2);
}
public void TakeBooting(int sleepTime = 10)
{
lock (_lockObj)
{
if (_taskRunningList.Count >= _maxRun)
{
_taskRunningList = _taskRunningList.Where(it => !it.IsCompleted).ToList();
}
while (_taskRunningList.Count < _maxRun && _taskQueue.Count > 0)
{
var t = _taskQueue.Dequeue();
_taskRunningList.Add(t);
t.Start();
}
}
System.Threading.Thread.Sleep(sleepTime);
}
public void Enqueue(Task task)
{
lock (_lockObj)
{
_taskQueue.Enqueue(task);
}
TakeBooting(0);
}
public void WaitAll()
{
while (_taskQueue.Count > 0)
{
TakeBooting();
}
Task.WaitAll(_taskRunningList.ToArray());
}
}
使用示例:
void Test()
{
var mtm = new MutilTaskManager();
foreach(int i in(new int[10]))
{
while (mtm.IsQueueFull)
{
mtm.TakeBooting();
}
mtm.Enqueue(new Task(myTask));
}
}
void myTask()
{
//read data
//do something
}
{
var mtm = new MutilTaskManager();
foreach(int i in(new int[10]))
{
while (mtm.IsQueueFull)
{
mtm.TakeBooting();
}
mtm.Enqueue(new Task(myTask));
}
}
void myTask()
{
//read data
//do something
}