2

I've a piece of code like this:

  foreach (var e in foobar)
    {
      var myObj = new MyObj();

        GenericResult res = soapClient.doSomething(e);
        if(res.success == true){
            myObj.a = e.a;
            myObj.b = e.b;
        }
    }

Every soapRequest takes about 500 milliseconds and sometime foobar is 1000+ elements so I'm wasting a lot of time waiting for the soapClient response. I've tried using Parallel.ForEach but it doesn't work because the SOAP provider accept only serialized requests. The provider suggest using async calls like soapClient.doSomthingAsync the problem is I haven't anything to do until I got the soapClient response.

The only solution I'm thinking of is using a Parallel.ForEach and a lock in the soap call

Federico
  • 789
  • 1
  • 6
  • 29
  • 2
    If you have to make 1000 requests then you have to make 1000 requests... perhaps you could look at a better model for the SOAP API you're calling - is that under your control? Can you make multiple instances of `soapClient`? – Dan Puzey Dec 04 '13 at 15:16
  • @DanPuzey no the API aren't under my control and I cannot use more instances of soapClient because the check for multiple requst are account wise (I'm using an API key). I'm using a Parallel For with a lock right now and it's slight more fast. I think this is the best solution :( – Federico Dec 04 '13 at 15:31
  • Do you know if this server is using HTTP 1.1?...which uses persistent connections by default. Otherwise if it's HTTP 1.0, you could request that the connection is kept open (Keep-Alive), so that you don't have to keep going through the TCP handshaking for each request. You'll need to look at the traffic on the wire (with WireShark/Fiddler)...http://stackoverflow.com/questions/4699013/does-webclient-use-keepalive ... Also, how are you generating your "proxy" (Add Service Reference, or Add Web Reference?)...is it WCF? (maybe you are hitting some throttling limits) – Colin Smith Dec 04 '13 at 16:00
  • You could also increase the "connection" limit to that host .... http://blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx – Colin Smith Dec 04 '13 at 16:05
  • 1
    You can't speed it up. You can request that the owner add methods to work with bulk data, what you want to do here. It would perform much better just to make just one call and give it a list of e's and get a list of results back. – user743414 Dec 04 '13 at 16:12

1 Answers1

0

Just a few things you could try out.

  • What type of authentication is applied to the service call. If the service etc. authenticates against an AD, you should ensure that only the first call is authenticated and the rest of the calls just piggybacks on that. An AD authentication can take substantial amount of time (0.3 - 1.0 s)

  • Try installing Fiddler and use it as a WCF proxy. Fiddler will give you the means to break down the time being spent in various parts of the execution of the service call.

  • Have you tried to ping the server you target - are the ping timings acceptable?.

  • How much time is being spent on the first invocation, compared to the following calls. The first call is always going to take a significant amount of time as the CLR runtime have to generate a boat load of dynamic XML code. Just generating the XmlSerializer JIT code is costly, as it dynamically generates C# code, kicks of the CSC compiler and load the generated DLL. You might have a look at the SGEN tool, which makes it possible to generate the XmlSerializer DLL's at compile time and instead of runtime (note this will only help on the first execution timings)

I can't see how much time is actually being spent on the server side, inside the execution of the doSomething(), so it's difficult to see how much time is actually being spent on the network. Faulty network hardware, cables, switches as well as firewalls, routing tables, SLA's etc. might have a negative impact on what performance you can get out of this.

Of cause as already mentioned, having such a chatty interface as you have to use, is far from optimal and the service owner might run into all sorts of server side performance problems, if this is their normal way of exposing interfaces - but that is another story :)

ahybertz
  • 514
  • 4
  • 9