Dienstag, 3. Januar 2017

Performance Profiling WCF Service running in WCF Test Client

I know the topic itself sounds a bit old school, but despite what many of my colleagues say, I think WCF is still alive and you might encounter it along your way. Furthermore I found it surprisingly hard to get the configration right to use Visual Studio Performance Profiling on a WCF Service that is running in the WCF Test Client - and is therefore not (yet) deployed to IIS. I mean the kind of WCF Application that you can start by simply hitting F5 and get going using the test client.

So as a note to myselft and hopefully as a help for someone else, here ist how I did it.

Choose Analyze | Performance Profiler (Alt + F2 using the standard shortcuts). Then go through the Performance Wizard.

Page 1 of 4: Specify the profiling method

Choose Instrumentation.

Page 2 of 4: Choose the modules to profile using the instrumentation method

Choose One or more available projects and select the WCF Service Project.

Page 3 of 4: These are things you may want to specify about the non-launchable project(s) you are going to profile

This is the tricky one. The thing is, to use the test client you must not start the test client. You must start the WCF Test Service Host. So set the Executeable path to

C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\WcfSvcHost.exe

Modyfiy the path as needed for your Visual Studio version. As Command-line arguments pass the following:

/service:<YourServiceProjectName>.dll /config:<YourServiceProjectName>.dll.config

Fill in the the name of your service project appropriately. The name of the config file points to the app.config file in your project, which is being renamed during compilation. As Working directory set

C:\<Path to my service library project>\bin\Debug\

Page 4 of 4: You have completed specifying settings for your new performance session

You might probably want to uncheck the Launch profiling after the wizard finishes checkbox to check the settings that have been created.

Tweaking the settings

Now your performance Wizard should look like this. That was not the final soultion for me, I needed to further tweak these settings.

Figure 1: The performance profiler after finishing the wizard

So, open the properties of your service project node. On the launch tab check Override project settings and repeat the settings you did before:
Executable to launch: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\WcfSvcHost.exe 
Arguments: /service:<YourServiceProjectName>.dll /config:<YourServiceProjectName>.dll.config
Working Directory: C:\<Path to my service library project>\bin\Debug\

Then delete the second node. You might as well delete the first node and rename the second. Maybe the intial version works too, but I ended up with this after running a profiling session:

Figure 2: The final performance profiler after running a session

For the records, here is the content of my .psess file, of course names and Guids will differ in your file, but sometimes it helps to have just the bits:

<?xml version="1.0" encoding="UTF-8"?>
<VSPerformanceSession Version="1.00">
  <Options>
    <Solution>WCFServices.sln</Solution>
    <CollectionMethod>Instrumentation</CollectionMethod>
    <AllocationMethod>None</AllocationMethod>
    <AddReport>true</AddReport>
    <ResourceBasedAnalysisSelected>true</ResourceBasedAnalysisSelected>
    <UniqueReport>Timestamp</UniqueReport>
    <SamplingMethod>Cycles</SamplingMethod>
    <CycleCount>10000000</CycleCount>
    <PageFaultCount>10</PageFaultCount>
    <SysCallCount>10</SysCallCount>
    <SamplingCounter Name="" ReloadValue="00000000000f4240" DisplayName="" />
    <RelocateBinaries>false</RelocateBinaries>
    <HardwareCounters EnableHWCounters="false" />
    <EtwSettings />
    <PdhSettings>
      <PdhCountersEnabled>false</PdhCountersEnabled>
      <PdhCountersRate>500</PdhCountersRate>
      <PdhCounters>
        <PdhCounter>\Arbeitsspeicher\Seiten/s</PdhCounter>
        <PdhCounter>\Physikalischer Datentr&amp;amp;amp;amp;amp;#228;ger(_Total)\Durchschnittl. Warteschlangenl&amp;amp;amp;amp;amp;#228;nge des Datentr&amp;amp;amp;amp;amp;#228;gers</PdhCounter>
        <PdhCounter>\Prozessor(_Total)\Prozessorzeit (%)</PdhCounter>
      </PdhCounters>
    </PdhSettings>
  </Options>
  <ExcludeSmallFuncs>true</ExcludeSmallFuncs>
  <InteractionProfilingEnabled>false</InteractionProfilingEnabled>
  <JScriptProfilingEnabled>false</JScriptProfilingEnabled>
  <PreinstrumentEvent>
    <InstrEventExclude>false</InstrEventExclude>
  </PreinstrumentEvent>
  <PostinstrumentEvent>
    <InstrEventExclude>false</InstrEventExclude>
  </PostinstrumentEvent>
  <Binaries>
    <ProjBinary>
      <Path>WCFServices\obj\Debug\WCFServices.dll</Path>
      <ArgumentTimestamp>01/01/0001 00:00:00</ArgumentTimestamp>
      <Instrument>true</Instrument>
      <Sample>true</Sample>
      <ExternalWebsite>false</ExternalWebsite>
      <InteractionProfilingEnabled>false</InteractionProfilingEnabled>
      <IsLocalJavascript>false</IsLocalJavascript>
      <IsWindowsStoreApp>false</IsWindowsStoreApp>
      <IsWWA>false</IsWWA>
      <LaunchProject>false</LaunchProject>
      <OverrideProjectSettings>true</OverrideProjectSettings>
      <LaunchMethod>Executable</LaunchMethod>
      <ExecutablePath>C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\WcfSvcHost.exe</ExecutablePath>
      <StartupDirectory>WCFServices\bin\Debug\</StartupDirectory>
      <Arguments>/service:WCFServices.dll /config:WCFServices.dll.config</Arguments>
      <NetAppHost>IIS</NetAppHost>
      <NetBrowser>InternetExplorer</NetBrowser>
      <ExcludeSmallFuncs>true</ExcludeSmallFuncs>
      <JScriptProfilingEnabled>false</JScriptProfilingEnabled>
      <PreinstrumentEvent>
        <InstrEventExclude>false</InstrEventExclude>
      </PreinstrumentEvent>
      <PostinstrumentEvent>
        <InstrEventExclude>false</InstrEventExclude>
      </PostinstrumentEvent>
      <ProjRef>{582C5667-EF99-4934-BD8C-938E75803D39}|WCFServices\WCFServices.csproj</ProjRef>
      <ProjPath>WCFServices\WCFServices.csproj</ProjPath>
      <ProjName>WCFServices</ProjName>
    </ProjBinary>
  </Binaries>
  <Reports>
    <Report>
      <Path>WcfSvcHost160926.vsp</Path>
    </Report>
    <Report>
      <Path>WcfSvcHost160927.vsp</Path>
    </Report>
  </Reports>
  <Launches>
    <ProjBinary>
      <Path>:PB:{582C5667-EF99-4934-BD8C-938E75803D39}|WCFServices\WCFServices.csproj</Path>
    </ProjBinary>
  </Launches>
</VSPerformanceSession>


So, this is it. Now you should be able to find your performance bottleneck in your WCF Code!




Keine Kommentare:

Kommentar veröffentlichen