Reputation: 37837
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--;
}
Upvotes: 2
Views: 1682
Reputation: 231
Have you ever tried the parallel for each? It's simple.
Here a MSDN example
Parallel.ForEach(concurrentJobs , currentJob =>
{
processJob(currentJob);
});
Upvotes: 0
Reputation: 35905
Looks like you have a producer-consumer model. In this case Parallel
class won't do you any good, because a new job can come any time. You can only use Parallel
class when you know beforehand what you need to do.
If, however, a new job can come any time I would use the following approach.
Write a separate long-running Task
or use Thread
. This thread receives jobs from network (such as from a queue or a database) or whatever and puts items into the shared memory.
Use BlockingCollection
to add and take jobs. This acts as a mediator between producer and consumer.
Exactly the same as producer - a separate Thread
that checks the shared memory for any available item. Once an item is retrieved from a queue you can process it at will.
Now if you have such separation, you can easily spawn several producers and consumers, each running in its own thread.
Upvotes: 3
Reputation: 127563
Similar to Romulo's answer, but a little more fleshed out.
First you need to turn your pollForJob()
function to an IEnumerable
private IEnumerable<Job> JobEnumerator()
{
Job job;
while((job = pollForJob()) != null)
{
yield return job;
}
}
Then you can use it with the Parallel.ForEach class
Parallel.ForEach(JobEnumerator(),
new ParallelOptions() {MaxDegreeOfParallelism = 5},
processJob);
This will block on the line Parallel.ForEach
but it will run 5 instances of the processJob(Job job)
function at the same time.
Upvotes: 0