我正在轮询外部队列以获取作业请求,然后处理作业(大约需要1分钟)。目前,我正在同步这样做,效率很低,因为如果有10个工作,则需要10分钟。该机器可以同时处理多达5个作业,因此它应该能够在约2分钟内处理10个作业。
我从未做过多线程,我曾尝试阅读async,await,Task.Run,但是没有成功实现它。有关实现此伪代码的简单方法的任何建议吗?
while(concurrentJobs <= 5)
{
job = pollForJob(); // synchronous
processJob(job); // want to do this in background so that I can poll for next job
}
void processJob(job)
{
concurrentJobs++;
doStuff(); // takes 1 minute
concurrentJobs--;
}
答案 0 :(得分:3)
看起来你有一个生产者 - 消费者模型。在这种情况下,Parallel
课程对你没有任何好处,因为任何时候都可以来一份新工作。当您事先知道需要做什么时,您只能使用Parallel
课程。
但是,如果我可以随时使用新工作,我会使用以下方法。
写一个单独的长期Task
或使用Thread
。该线程从网络(例如来自队列或数据库)或其他任何东西接收作业,并将项目放入共享内存。
使用BlockingCollection
添加和接受工作。这充当了生产者和消费者之间的中介。
与生成器完全相同 - 一个单独的Thread
,用于检查共享内存中是否有任何可用项。从队列中检索项目后,您可以随意处理它。
现在,如果你有这样的分离,你可以很容易地产生几个生产者和消费者,每个生产者和消费者都在自己的线程中运行。
答案 1 :(得分:0)
你有没有试过每个并行?这很简单。
这是MSDN example
Parallel.ForEach(concurrentJobs , currentJob =>
{
processJob(currentJob);
});
答案 2 :(得分:0)
与Romulo's answer相似,但更加充实。
首先,您需要将pollForJob()
功能转换为IEnumerable
private IEnumerable<Job> JobEnumerator()
{
Job job;
while((job = pollForJob()) != null)
{
yield return job;
}
}
然后您可以将其与Parallel.ForEach类
一起使用Parallel.ForEach(JobEnumerator(),
new ParallelOptions() {MaxDegreeOfParallelism = 5},
processJob);
这将阻止Parallel.ForEach
行,但它将同时运行processJob(Job job)
函数的5个实例。