我正在编写一个针对 SQL Server 的轮询系统。检索任务时,它们会使用Task.Factory.StartNew()
. 整个事情都在一个无限循环中,我只想允许 N 个并发任务。
while(true)
{
// create connection
while(_concurrentTasks < _allowedTasks)
{
// get job info
if(!reader.HasRows) break; // no work to do.
while(reader.Read())
{
// fill JobInfo entity from reader
_taskCollection.Add(Task.Factory.StartNew(() => ProcessJob(jobInfo)));
_concurrentTasks++;
}
}
// could break for 1 of 2 reasons, threshold met or nothing to do
if((_concurrentTasks < _allowedTasks)
{
// sleep for a predetermined period of time
Thread.Sleep(60000);
}
else
{
// wait for one thread to complete and then get more jobs
Task.WaitAny(_taskCollection.ToArray);
}
}
我不确定在这种情况下哪个集合最适合使用,或者如何清理已完成的任务。
如果我将清理代码放在任务本身中,我可以List<Task>
与Task.CurrentId
属性一起使用来识别集合中的项目,但我不相信我可以在任务本身中处理集合中的 Task 对象;另请注意,该集合必须是线程安全的。
如果我将某种清理代码放在任务之外(在主线程中),我不需要线程安全集合,但我不知道任务何时在主线程中完成。
那么,我应该使用哪个集合来维护并发任务的列表/数组以便我可以使用WaitAny()
以及如何在完成时清理列表?