8

I'm calling a .net webservice from my .net winforms app, both in framework 4.0. During the execution of the program, the first time the webservice has a method called, the call takes ~10-12 seconds. Subsequent calls take ~1-2 seconds. Subsequent calls, even when the web reference instance is recreated, are still ~1-2 seconds. When the winforms app is restarted, the first call delay occurs again, but subsequent calls are responsive.

The instance of the web reference is being created prior to the call occuring, and is not part of the delay.

XmlSerializers for the winforms app are being generated (and used, as far as I know, but I'm not sure how to verify this).

The delay is not occuring because of a first-run compilation on the webservice side. This is a production webservice that is being used throughout the day, and its apppool is remaining in memory. As far as I can see, the delay is occurring either on the client side, or between the client and the server for that first call, but not subsequent calls.

Not sure what to check next. Any ideas?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Brian M.
  • 826
  • 1
  • 8
  • 16
  • 1
    Keep in mind that the first call is going to be slower, however, it shouldn't be that slow. – tier1 Apr 18 '13 at 14:45
  • 1
    I suspect the answer probably lies somewhere in this question/answer combo : http://stackoverflow.com/questions/6988981/webclient-is-very-slow In particular, I'm looking at proxy issues. – spender Apr 18 '13 at 14:45
  • 1
    Do you have "Automatically detect settings" for your proxy in internet options on the faulting machine? – spender Apr 18 '13 at 14:47
  • @tkcsam: Yes, I expect a small amount delay, but certainly not what I'm seeing. – Brian M. Apr 18 '13 at 14:48
  • @spender: I did have that set, so I unchecked it and ran the app. First call took 2-3 seconds, as one would expect, so I'd guess that this setting is related. Problem is that this app runs on around 1,200 machines across the enterprise, and trying to convince the desktop support group to disable that setting would be, well, neigh impossible i'd guess. But, I'll take that as a step in the right direction and see if There's a workaround to be found related to this setting. Thanks – Brian M. Apr 18 '13 at 14:50
  • Good luck... there's a ton of info on this problem. – spender Apr 18 '13 at 14:52
  • You could probably use detailed IIS request logs to determine whether the delay is coming from the client or web side - do you have any information on that? – Dan Puzey Apr 18 '13 at 14:55

5 Answers5

9

As spender had indicated, the issue had to do with the proxy detection. Turning that off in Internet Explorer solved the problem, but was not feasible to do in my situation.

Instead, there is a workaround to bypass the use of the default proxy, and therefore the automatic detection.

Adding these entries to the app.config allows certain URLs to bypass the proxy:

<configuration>
    <system.net>
        <defaultProxy>
            <bypasslist>
                <add address="server/domain name" />
            </bypasslist>
        </defaultProxy>
    </system.net>
</configuration>

More information can be found here: <defaultProxy Element> on MSDN

Brian M.
  • 826
  • 1
  • 8
  • 16
  • You have winforms client app that runs on the desktop and changing internet explorer options helps with that? Just curios, please let me know! – Mare Infinitus Jul 10 '13 at 06:17
  • 1
    @MareInfinitus: It's not really an Internet Explorer option per se, it's an option of the wininet API, which Internet Explorer also uses and provides a GUI for configuring. – Ben Voigt Aug 28 '13 at 14:53
2

try setting the proxy to an empty WebProxy, ie:

request.Proxy = new WebProxy(); 

or you can override the proxy settings in the .Config file for your application using the defaultProxy key in the system.net section. The following disables automatic Proxy detection:

<configuration >
  <system.net>
    <defaultProxy>
      <proxy bypassonlocal="true" usesystemdefault="false" />
    </defaultProxy>
</system.net>
</configuration>

http://weblog.west-wind.com/posts/2005/Dec/14/Slow-Http-client-calls-from-ASPNET-20-Make-sure-you-check-your-Proxy-Settings

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Prash
  • 114
  • 8
1

Apologize for the necro-add, but this issue has come up a number of times for me, and I have a habit of forgetting all the aspects of this issue each time. So here's the list (some of which other people mentioned)

  • Change your System.ServiceModel.BasicHttpBinding so that the BypassProxyOnLocal and UseDefaultWebProxy are both false. (You can decide whether you want to do this in a config file or via code.)
  • Change the ‘Generate Serialization Assembly’ in the projects ‘Build’ properties to ‘On’ instead of ‘Auto’
  • Make sure you’re using a modern .NET framework. 4.6.1 is about 60 MS faster than 4.5.2 on the first request, for instance.
  • Do your performance testing on a Release Executable, not within VisualStudio (VS adds a large additional overhead on the initial call that is not reflected in the actual release .exe build.)
  • If you're working with a service/site that continually run, definitely consider sending a dummy request to the server upon startup - simply to get .NET to serialize the connection up front. Likewise, if you're writing a run-and-quit app, consider writing a background dummy request while the program is starting up.
  • Make sure the service you're connecting to doesn't recycle very often. Every time the app pool recycles on an IIS service, the first request coming in after recycle can take awhile.
  • Make sure the service you're connecting to doesn't hibernate. By default, a service hibernates after 20 minutes of inactivity - and the next request that comes in has a delay similar to a post-recycle request.
Kevin
  • 2,133
  • 1
  • 9
  • 21
0

I have suffered this problem many times - man I hate it!!! lol Whilst I have never conclusively solved it, you could try a couple of things. Firstly, make a call to the web service during start up and get the 'pain' out of the way first! Secondly, try messing with the web service's IIS application pool - make it so that it never recycles itself or at least does so at an un-Godly hour of the morning or perhaps per 10000 requests.

I know this probably isn't that great an answer, but hope it helps a little!


EDIT :

Part of the issue is that the web service isn't 'always' up - it goes to sleep, recycles etc until needed. It would be worth reading up on keeping web-services alive, 5 9s up time etc!

Bertie
  • 733
  • 5
  • 16
  • Won't help. OP has ticked off these issues in the question. – spender Apr 18 '13 at 14:50
  • Correct. Apppool isn't related here. but thanks for the suggestion – Brian M. Apr 18 '13 at 14:51
  • This webservice, during the time of my testing, is indeed 'always' up. It's being called by clients 2-3 times per second, from 7am to 7pm or so. I understand what you're saying in regards to app pool recycles and such like that, but it isn't the case here. – Brian M. Apr 18 '13 at 14:57
  • Fair enough - just covering the bases! The only way I ever got round this was to do an initial dummy call to the service when my client started. Sorry can't be more help than that currently! – Bertie Apr 18 '13 at 15:08
  • So would I be right in thinking that the clients currently calling the service are web clients and your issue is from a .Net application that used the Web Service Reference wizard? – Bertie Apr 18 '13 at 15:32
  • Clients are both .net winforms, and .net webforms, but in my example, it's a winforms app. All clients have had the web reference added through visual studio's Add Web Reference. (solution has already been found; see below) – Brian M. Apr 18 '13 at 16:57
0

I've added these settings on my basicHttpBinding, disabling the automatic proxy detection and gaining a great speedup on first execution time. This of course works well if you are into intranet environment, or you know you do not need any proxy at all.

bypassProxyOnLocal="false"

useDefaultWebProxy="false"

Hope this helps.