Stack Man
Stack Man

Reputation: 886

Simultaneous asynchronous API call

I have a Windows application which must make an API call exactly 20 times every second.

The requirement is that the reads must be done very CLOSE TO SIMULTANEOUSLY (within milliseconds).

The following code uses a timer that runs every second. aaList is a list containing 20 objects.

With the current code I have, unfortunately, some reads are done at different times (half a second later sometimes) so obviously a bottleneck is forming somewhere.

Can anyone suggest how my requirements can be achieved in a more simultaneous manner? (Perhaps I should be doing this in a different way?)

private void tmrAAProcess_Tick(object state)
{

     foreach (aa in aaList) {
          Task.Factory.StartNew(() =>
          {                       
             aa.ReadFromWebsite();
          }, TaskCreationOptions.LongRunning);

     }

}

Upvotes: 0

Views: 508

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 133950

One likely problem is that the ServicePointManager defaults to allowing only two concurrent connections to the same site. You'll have to change the DefaultConnectionLimit property, for one.

Another problem is that the TPL is going to limit your parallelism. I don't know what your ReadFromWebsite method does, but if it's making a blocking call (i.e. HttpWebRequest.GetResponse), it's likely that you'll just end up with a bunch of queued tasks.

I can't imagine that you'll get a sustained rate of 50 ms per request. Communication time alone will probably exceed that unless it's an in-house server. Your machine will run out of connections after a while, because it's waiting on responses. Either that or you'll run out of memory with all those queued tasks.

If you want to make this work, you'll have to at least:

  1. Modify the ServicePointManager.DefaultConnectionLimit
  2. Make asynchronous web requests
  3. Explicitly limit the number of concurrent outstanding requests using a queue or a semaphore or something similar.

You should keep a running average of the response time for the last N (some reasonably small number like 20) requests, and not make requests faster than that.

Upvotes: 1

Related Questions