2

I'm polling an external queue for job requests, then process the job (which takes ~1 minute). Currently, I'm doing it synchronously, which is inefficient because if there were 10 jobs, it would take 10 minutes. The machine can handle up to 5 jobs at the same time, so it should be able to process 10 jobs in ~2 minutes.

I've never done multi-threading, I've tried to read about async, await, Task.Run, but haven't had any success implementing it. Any suggestions on a simple way to implement this pseudocode?

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--;
}
4

3 回答 3

3

看起来你有一个生产者 - 消费者模型。在这种情况下Parallel,上课对你没有任何好处,因为新工作随时可能出现。Parallel只有事先知道自己需要做什么,才能使用类。

但是,如果可以随时找到新工作,我会使用以下方法。

制片人

编写一个单独的长时间运行Task或使用Thread. 该线程从网络(例如从队列或数据库)或其他任何地方接收作业,并将项目放入共享内存中。

共享内存

用于BlockingCollection添加和获取作业。这充当了生产者和消费者之间的中介。

消费者

与生产者完全相同 -Thread检查共享内存中是否有任何可用项目的单独的。从队列中检索到项目后,您可以随意处理它。


现在,如果您有这样的分离,您可以轻松地产生多个生产者和消费者,每个生产者和消费者都在自己的线程中运行。

于 2013-09-05T19:36:19.037 回答
0

你有没有尝试过每个平行?这很简单。

这是一个 MSDN示例

Parallel.ForEach(concurrentJobs , currentJob =>
{
    processJob(currentJob);
});
于 2013-09-05T19:20:41.993 回答
0

类似于Romulo 的回答,但更加充实。

首先你需要把你的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 个实例。

于 2013-09-05T19:27:25.130 回答