Hi, we have a problem with wcf speed on Windows 7 and it looks like common problem. The situation is this: we have a simple WCF service (actualy lot's of them, all behave the same way) and i client, who makes lot's of small queries to that wcf service. WCF service and database are in the same server, that server is Windows 2003. Problem is, that when we moved our development to windows 7, these calls started to take much more time, than before. I've investigated these things: 1) First WCF service was on IIS7 in Windows 7, database was on separate Windows 2003 server, so we thought may be IIS7 problem. So we moved WCF service to the same server, where database is. No difference. 2) If we run client from XP/Windows 2003, it runs faster (7-10 times). so it looks like some kind of Windows 7 networking problem (also i need to mention, that we tried from several Windows 7 machines, just to be sure). 3) So if it's networking, we've googled and tryed various tips: - netsh interface tcp set global autotuning=disabled (also autotuning=high), no effect - uninstall remote differential compression, no effect - tryed to change network speed to 1gbps duplex (didn't worked at all, guess newtork not ready for that), to 100mbps duplex (didn't helped) We made a little test client, wich makes 100 queries to same webservice method (GetProjectById) with random chosen id from existing id list:
List<long> times = new List<long>();
Stopwatch stopWatch = new Stopwatch();
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
var id = ids[rnd.Next(ids.Count)];
stopWatch.Start();
var projectItem = client.GetProjectById(id);
stopWatch.Stop();
times.Add(stopWatch.ElapsedMilliseconds);
stopWatch.Reset();
}
Console.WriteLine(string.Format("{0} times less than 50 ms", times.Count(item => item < 50)));
Console.WriteLine(string.Format("{0} times less than 100 ms", times.Count(item => item >= 50 && item < 100)));
Console.WriteLine(string.Format("{0} times less than 500 ms", times.Count(item => item >= 100 && item < 500)));
Console.WriteLine(string.Format("{0} times less than 1000 ms", times.Count(item => item >= 500)));
times.ForEach(item => Console.WriteLine(item));
Console.ReadLine();
Results are interesting: 42 times less than 50 ms 1 times less than 100 ms 0 times less than 500 ms 57 times less than 1000 ms 604 59 507 15 521 14 14 517 511 523 15 14 517 516 15 14 14 511 15 506 14 517 12 514 516 516 520 524 15 16 514 520 517 513 516 509 14 518 15 14 517 520 15 518 516 15 14 517 15 512 15 14 14 14 14 513 15 510 15 14 507 509 516 513 14 517 15 516 505 14 15 12 524 517 516 506 14 14 517 520 15 509 15 521 517 505 518 15 511 516 506 15 512 516 14 14 508 510 516 15 as you see, there are several interesting things: 1) time is sometimes 10-20ms, sometimes 500-520ms 2) half queires fit in 10-20ms, half in 500-520ms 3) there's no clear pattern - sometimes several queries in a row are in 500-520ms interval, sometimes several queries in a roe are in 10-20ms interval, sometimes they mixup completly. 4) when test is made on Windows2003/XP, most queries fit under 50ms. If you have any idea, what else we could check, please write your ideas. | | Giedrius Banaitis | Hi Giedrius, 1. Did you run your client from Vista at all? 2. Hope you are testing this in release mode exe on client (on both XP, W2k3 and Win7) 3. If you look at this bug report- http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=475643. Seems that its a known issue with VS debugger in VS 2008. Someone else seems to be getting this issue as well- http://stackoverflow.com/questions/1369694/slow-web-service-and-wcf-service-calls-from-windows-7Although I don't think yourissue is the same, its still worth trying once by using useDefaultWebProxy="false". I have a production WCF service with a client exe, will check on similar lines and let you know if I see any noticable delay. Thanks, -Phani | | Phani_tpk | 1. Have no vista by hand, so only windows2003/windows 7/xp available for tests. 2. No, i'm testing in debug mode and that matters, because i need to debug application and every debug session taking to loadat least3 minutes, that makes hard to concentrate :) 3. I've looked at the report, but i don't think this is the case, because i was running test not from VS 2008 and without attached debugger. regarding stackoverflow link, i saw it before and forgot to mention, that i've tried that too, didn't worked. further info - i've wrote sample wcf test (simply created new wcf service web application), hosted it on IIS 6 on windows 2003write a client that uses it and got same result (actualy result is even clearer now - all requests from Windows 7 took > 500ms, all requests from XP took < 10ms). what's even more interesting, that even if i host this wcf service on same windows7 machine as client is running, i'm getting 500ms for a query. code and configuration follows:
//Client:
static void Main(string[] args)
{
PingService.PingServiceClient client = new PingServiceClient();
List<long> times = new List<long>();
Stopwatch stopWatch = new Stopwatch();
Random rnd = new Random();
for (int i = 0; i < 100; i++)
{
var composite = new CompositeType() {BoolValue = true, StringValue = Guid.NewGuid().ToString()};
stopWatch.Start();
var projectItem = client.GetDataUsingDataContract(composite);
stopWatch.Stop();
times.Add(stopWatch.ElapsedMilliseconds);
stopWatch.Reset();
}
Console.WriteLine(string.Format("{0} times less than 50 ms", times.Count(item => item < 50)));
Console.WriteLine(string.Format("{0} times less than 100 ms", times.Count(item => item >= 50 && item < 100)));
Console.WriteLine(string.Format("{0} times less than 500 ms", times.Count(item => item >= 100 && item < 500)));
Console.WriteLine(string.Format("{0} times less than 1000 ms", times.Count(item => item >= 500)));
times.ForEach(item => Console.WriteLine(item));
Console.ReadLine();
}
Client config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPingService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="">
</transport>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://kasalotas/WcfSpeedService/PingService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPingService"
contract="PingService.IPingService" name="BasicHttpBinding_IPingService" />
</client>
</system.serviceModel>
</configuration>
Web service config:
<?xml version="1.0"?><br/><!--<br/> Note: As an alternative to hand editing this file you can use the <br/> web admin tool to configure settings for your application. Use<br/> the Website->Asp.Net Configuration option in Visual Studio.<br/> A full list of settings and comments can be found in <br/> machine.config.comments usually located in <br/> \Windows\Microsoft.Net\Framework\v2.x\Config <br/>--><br/><configuration>
<br/> <configSections><br/> <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"><br/> <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"><br/> <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/><br/> <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"><br/> <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" /><br/> <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /><br/> <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /><br/> <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" /><br/> </sectionGroup><br/> </sectionGroup><br/> </sectionGroup><br/> </configSections>
<br/> <appSettings/><br/> <connectionStrings/>
<system.web><br/> <!--<br/> Set compilation debug="true" to insert debugging <br/> symbols into the compiled page. Because this <br/> affects performance, set this value to true only <br/> during development.<br/> --><br/> <compilation debug="false">
<assemblies><br/> <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/><br/> <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> </assemblies>
</compilation><br/> <!--<br/> The <authentication> section enables configuration <br/> of the security authentication mode used by <br/> ASP.NET to identify an incoming user. <br/> --><br/> <authentication mode="Windows" /><br/> <!--<br/> The <customErrors> section enables configuration <br/> of what to do if/when an unhandled error occurs <br/> during the execution of a request. Specifically, <br/> it enables developers to configure html error pages <br/> to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"><br/> <error statusCode="403" redirect="NoAccess.htm" /><br/> <error statusCode="404" redirect="FileNotFound.htm" /><br/> </customErrors><br/> -->
<br/> <pages><br/> <controls><br/> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> </controls><br/> </pages>
<httpHandlers><br/> <remove verb="*" path="*.asmx"/><br/> <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/><br/> </httpHandlers><br/> <httpModules><br/> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> </httpModules>
<system.codedom><br/> <compilers><br/> <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"<br/> type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"><br/> <providerOption name="CompilerVersion" value="v3.5"/><br/> <providerOption name="WarnAsError" value="false"/><br/> </compiler><br/> </compilers><br/> </system.codedom>
<system.web.extensions><br/> <scripting><br/> <webServices><br/> <!--<br/> Uncomment this section to enable the authentication service. Include <br/> requireSSL="true" if appropriate.
<authenticationService enabled="true" requireSSL = "true|false"/><br/> --><br/> <!--<br/> Uncomment these lines to enable the profile service, and to choose the <br/> profile properties that can be retrieved and modified in ASP.NET AJAX <br/> applications.
<profileService enabled="true"<br/> readAccessProperties="propertyname1,propertyname2"<br/> writeAccessProperties="propertyname1,propertyname2" /><br/> --><br/> <!--<br/> Uncomment this section to enable the role service.
<roleService enabled="true"/><br/> --><br/> </webServices><br/> <!--<br/> <scriptResourceHandler enableCompression="true" enableCaching="true" /><br/> --><br/> </scripting><br/> </system.web.extensions><br/> <!--<br/> The system.webServer section is required for running ASP.NET AJAX under Internet<br/> Information Services 7.0. It is not necessary for previous version of IIS.<br/> --><br/> <system.webServer><br/> <validation validateIntegratedModeConfiguration="false"/><br/> <modules><br/> <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> </modules><br/> <handlers><br/> <remove name="WebServiceHandlerFactory-Integrated"/><br/> <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"<br/> type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"<br/> type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/><br/> <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /><br/> </handlers><br/> </system.webServer>
<br/> <system.serviceModel><br/> <services><br/> <service name="WcfSpeedService.PingService" behaviorConfiguration="WcfSpeedService.Service1Behavior"><br/> <!-- Service Endpoints --><br/> <endpoint address="" binding="basicHttpBinding" contract="WcfSpeedService.IPingService"><br/> <!-- <br/> Upon deployment, the following identity element should be removed or replaced to reflect the <br/> identity under which the deployed service runs. If removed, WCF will infer an appropriate identity <br/> automatically.<br/> --><br/> <identity><br/> <dns value="localhost"/><br/> </identity><br/> </endpoint><br/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/><br/> </service><br/> </services><br/> <behaviors><br/> <serviceBehaviors><br/> <behavior name="WcfSpeedService.Service1Behavior"><br/> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --><br/> <serviceMetadata httpGetEnabled="true"/><br/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --><br/> <serviceDebug includeExceptionDetailInFaults="false"/><br/> </behavior><br/> </serviceBehaviors><br/> </behaviors><br/> <bindings> <br/> <basicHttpBinding> <br/> <binding name="MyBasicHttpBinding"> <br/> <security mode="None"> <br/> <transport clientCredentialType="None" /> <br/> </security> <br/> </binding> <br/> </basicHttpBinding><br/> </bindings><br/> </system.serviceModel><br/></configuration><br/>
| | Giedrius Banaitis | You certainly have got a very important point. I am able to reproduce this even with release production service and client. We have a smartclient client and WCF services hosted on Win2K3 box using IIS 6.0. I just moved to Win7 (on my laptop) a week back from Vista.
So tested the client from a XP box (2GB ram, 32 bit) and a Win7 box (my laptop- 4 GB ram, 64 bit).
And the results are as follows:
Win7- run1: 5 mins run2: 1 min and 15 secs run3: 1 min and 15 secs run4: 1 min and 25 secs run5: 3 mins and one off times I get response in 20 secs (happened twice for above 7 runs)
WinXP-
more or less consistent- around 30 secs
Since this was a production application didn't have counters, this is the same exe run on win7 and winxp. So definately something is fishy with WCF. Considering everything else remaining same.
This is for 779 records of data which is queried for. Biding is basicHttpBinding- for interoperability sake.
Would be nice to hear from Microsoft WCF product folks about their views. Even if my app were to be ruled out because of other 3rd party grids etc, your sample app says it all.
And in fact, I have been using this app on vista and never saw such latency. Although I didn't measure with stopwatch.
Thanks, -Phani | | Phani_tpk | Any suggestions? | | Giedrius Banaitis | Hi Giedrius, I have logged a bug on this on connect- https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=491484And have given a link to this thread. We can follow it up there. I have also sent an email to Dr. Nicolas Allen. Will post back if I see any update. I am sure if its an issue that they can reproduce, you can get a hotfix for this. Also, check if your company has a Microsoft Support tickets, if yes, then you can raise a Level 1 severity (if its productionbreak down) or Level 2 if you can wait couple of daysand you will have some solution for sure and thats an officialroute if you like. regards, -Phani | | Phani_tpk | Hi Phani, thanks a lot for your effort, let's see what will happen. | | Giedrius Banaitis | Is your system x64 or x86? because mine is x64 on which I am able to repro the behavior.
-Phani | | Phani_tpk | Mine is x64 also | | Giedrius Banaitis |
|