Reputation: 82341
I have a console application that runs a loop calling 4 WCF Web Services in a specific order.
Each iteration of the loop is not dependent on the previous or the next iteration.
Each iteration of the loop takes about 5 seconds.
I would like to use some parallel or async work to get this time down.
Basically, what I am thinking is that while I am waiting on one of the services, I could be getting another iteration calling one of the other 4 services.
However, in my attempts, this has not worked.
I have tried to do something like this:
dataRows.ToList().ForEach(async patientRow =>
{
// Calls made here. Example calls below:
var personData = await personOperations.SavePersonAsync(personRow);
var saveResponse = await orderingBrokerOperations
.SaveAsync(orderedTestContracts, personData);
printOperations.Print(saveResponse );
});
But this ends up front loading tons of the calls. (Meaning that the 1st web service gets blasted with many many requests.) Eventually one of the calls times outs because it is getting too many requests.
So then I tried this:
Parallel.ForEach(dataRows,
new ParallelOptions{MaxDegreeOfParallelism = 10}, (patientRow) =>
{
// WCF calls are made synchronously
});
This kept my calls from going overboard, but did not really increase the speed much.
I also tried doing this
Parallel.ForEach(dataRows,
new ParallelOptions{MaxDegreeOfParallelism = 10}, async (patientRow) =>
{
// Do the calls here. Each call is made using the await keyword.
});
but it had the same problems as the first option.
Out of frustration I then tried this:
long inProgress = 0;
dataRows.ToList().ForEach(async patientRow =>
{
inProgress++;
if (inProgress > 10)
Thread.Sleep();
// Do the calls here. Each call is made using the await keyword.
inProgress--;
});
This did not really speed things up either.
My Dev Servers are not really strong, but they should be strong enough to handle at least 10 calls at the same time. I am not sure what is going on.
Is there a good way to spread out the calls to my services without running synchronously?
Upvotes: 1
Views: 657
Reputation: 13495
Have a look at this implementation of ForEachAsync
by Stephen Toub. It should enable you to do what you want and it allows control of how many tasks you want to execute concurrently.
I would also recommend making your WCF calls asynchronous if possible. Have a look at this post for more detail.
On a final not if you want to execute many async operations concurrently, you do not await
them as you are kicking them off. You store each Task
in a list as they are being kicked off and then you used Task.WhenAll
to await
their completion.
Upvotes: 4