Multithreading 跟踪并发任务
我正在编写一个针对SQL Server的轮询系统。检索任务时,使用Multithreading 跟踪并发任务,multithreading,c#-4.0,collections,Multithreading,C# 4.0,Collections,我正在编写一个针对SQL Server的轮询系统。检索任务时,使用Task.Factory.StartNew()将任务卸载到新线程。整个过程都在一个无止境的循环中,我只允许N个并发任务 while(true) { // create connection while(_concurrentTasks < _allowedTasks) { // get job info if(!reader.HasRows) break; //
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);
}
}
while(true)
{
//创建连接
而(\u concurrentTasks<\u allowedTasks)
{
//获取工作信息
如果(!reader.HasRows)中断;//没有工作要做。
while(reader.Read())
{
//从读卡器填充JobInfo实体
_taskCollection.Add(Task.Factory.StartNew(()=>ProcessJob(jobInfo));
_concurrentTasks++;
}
}
//可能因以下两种原因之一而中断,达到阈值或无需执行任何操作
如果(_concurrentTasks<_allowedTasks)
{
//睡一段预定的时间
睡眠(60000);
}
其他的
{
//等待一个线程完成,然后获取更多作业
Task.WaitAny(_taskCollection.ToArray);
}
}
我不确定在这种情况下最好使用哪个集合,也不确定如何清理已完成的任务
如果我将清理代码放在任务本身中,我可以使用List
和task.CurrentId
属性来标识集合中的项,但我认为我无法在任务本身中处理集合中的任务对象;还要注意,集合必须是线程安全的
如果我在任务外部(主线程中)放置某种清理代码,我就不需要线程安全集合,但我不知道任务何时在主线程中完成
那么,我应该使用哪个集合来维护并发任务的列表/数组,这样我就可以使用
WaitAny()
,当一个任务完成时,我如何清理列表?我决定使用一个数组并在必要时循环它:
Task[] tasks = new Task[_allowedTasks];
while(true)
{
// create connection
while(_concurrentTasks < _allowedTasks)
{
// get job info
if(!reader.HasRows) break; // no work to do.
while(reader.Read())
{
for (int i = 0; i < tasks.Length; i++)
{
if (tasks[i] == null || tasks[i].IsCompleted)
{
// Dispose of Task at position i
nextSlot = i;
break;
}
}
// fill JobInfo entity from reader
tasks[nextSlot] = 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);
}
}
Task[]tasks=新任务[_allowedTasks];
while(true)
{
//创建连接
而(\u concurrentTasks<\u allowedTasks)
{
//获取工作信息
如果(!reader.HasRows)中断;//没有工作要做。
while(reader.Read())
{
for(int i=0;iProcessJob(jobInfo));
_concurrentTasks++;
}
}
//可能因以下两种原因之一而中断,达到阈值或无需执行任何操作
如果(_concurrentTasks<_allowedTasks)
{
//睡一段预定的时间
睡眠(60000);
}
其他的
{
//等待一个线程完成,然后获取更多作业
Task.WaitAny(_taskCollection.ToArray);
}
}
为什么要将其限制为N个并发任务?一次运行太多任务是否会影响性能?通常,TPL擅长运行“正确的”数字。@ChrisShain-我将让其中几个进程同时运行。如果我不限制它,一个进程可以占用所有作业,它们只会堆积在线程池队列中。你可以看看其他人制作的调度器,特别是LimitedConcurrencyLevel TaskScheduler.cs。我正在编写一个针对SQL Server的轮询系统r'-你不能使用触发器或者存储过程吗?@MartinJames-我想使用代理服务,但管理层拒绝了这个想法,所以我只能使用轮询服务。