HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Calling many web services asynchronously

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
servicesasynchronouslywebmanycalling

Problem

I need to process a bunch of completed orders (thousands). To make it faster, I'm using a SemaphoreSlim to schedule a number of orders to be processed in parallel. Every order goes through multiple web service calls to various APIs (SOAP, REST). Then I need to take the returned data and process it into a PDF. Here is what I am doing currently (note that this is in an ASP.NET app):

private async Task ProcessOrders(List orders)
{
    var allTasks = new List();
    var throttler = new SemaphoreSlim(initialCount: 5);

    foreach (var order in orders.Where(x => !x.HasError))
    {
        // do an async wait until we can schedule again
        await throttler.WaitAsync();

        // using Task.Run() to run the lambda in its own parallel
        // flow on the thread pool
        allTasks.Add(Task.Run(async () =>
        {
            try
            {
                // Call external web service here
                // Build order report PDF here
            }
            finally
            {
                throttler.Release();
            }
        }));
    }

    await Task.WhenAll(allTasks);
}


However, I'm new to TPL and I don't know if this is the right way to do something like this. If it's relevant, this app is hosted on Amazon's AWS cloud.

Solution

I'm not all that familiar with async/await (I really need to get going on this), but I find your code pretty clear, except why the magic number 5 is being used for an initialCount.

I like your usage of var, but the comments are a little redundant, they say nothing much that the code doesn't already tell.

It would have been nice to see the actual code in place of the placeholder comments in the try block - I'd expect to see a method call here; if that comment stands for code that actually implements what's described, you need to factor it out.

Also I would have indented the async task's body, but that's more of a nitpick.

I would probably also have introduced a var validOrders = orders.Where(order => !order.HasError); to make the foreach loop clearer. Not sure I like x for a name in the lambda: try to use meaningful names everywhere.

Context

StackExchange Code Review Q#61813, answer score: 6

Revisions (0)

No revisions yet.