WCF Tips: Achieving High Performance. List of Key Design Decisions and Tuning Parameters

3 ביולי 2008

8 comments

When working with WCF especially when middle-tier client applications uses Windows Communication Foundation, you sould always think about performance and take some major design decisions and tuning parameters.




  1. WCF client not generated as a proxy via SvcUtil.exe (Relevant more in .NET 3.0. In .NET 3.5 major performance improvement was made on WCF proxy creation).



    • Client shares service contract and schema (model classes as data contract).


    • Cache WCF proxy as a static member



      • One instance, once instance only, ever


      • Still thread-safe based on WCF under-the-covers network connection pool management
        Channels created directly via ChannelFactory


      • Hidden static channel exposed as a property


      • Getter/Setter logic does all initialization/abort/recreation as necessary


      • Maintains clean code in use of service operations


    • Expect up to 50% perfdegradation if you instance a generated proxy client class per Web Service call



      • Very different than ASMX


      • Same client caching approach in ASMX: no performance difference


  2. Static WCF Channel Logic code example:


private static object _channelLock= new object();


private static ChannelFactory<IMyService> _factory;


private static IMyService _channel;


 


public IMyService Channel


{


    get


    {


        IMyService localChannel = _channel;


 


        if (localChannel == null)


        {


            lock (_channelLock)


            {


                if (_factory == null)


                {


                    EndpointAddress remoteNodeEndPointAddress= new EndpointAddress("[someURI]");


                    _factory = new ChannelFactory<IMyService>("BasicHttpBindingMyServices", remoteNodeEndPointAddress);


                }


 


                if (_channel == null)


                {


                    _channel = _factory.CreateChannel();


                }


 


                return _channel;


            }


        }


 


        return localChannel;


    }


    set


    {


        lock (_channelLock)


        {


            if (((IChannel)_channel).State != CommunicationState.Opened)


            {


                ((IChannel)_channel).Abort();


                _channel = null;


            }


            if (_factory.State!= CommunicationState.Opened)


            {


                _factory.Abort();


                _factory = null;


            }


        }


    }


}


 


Service Operations Call (instanced per call):


 


public string SampleCall(string message)


{


    try


    {


        return this.Channel.SampleCall(message);


    }


    catch


    {


        this.Channel = null;


        throw;


    }


}


 


Now lets see some important Tuning Parameters:




  • Tcp binding is a custom binding, with binary encoding:

<customBinding>


  <binding name="CustomTcpBinding_PrimaryTradeServices">


    <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="32" maxSessionSize="4096">


      <readerQuotas maxDepth="64" maxStringContentLength="131072" maxArrayLength="16384"


              maxBytesPerRead="16384" maxNameTableCharCount="32768"/>


    </binaryMessageEncoding


    <tcpTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="524288"


            connectionBufferSize="65536" hostNameComparisonMode="StrongWildcard"


            channelInitializationTimeout="00:00:05" maxBufferSize="524288"


            maxPendingConnections="100" maxOutputDelay="00:00:00.2000000"


            maxPendingAccepts="100" transferMode="Buffered" listenBacklog="400"


            portSharingEnabled="false" teredoEnabled="false">


    <connectionPoolSettings groupName="default" leaseTimeout="00:05:00" idleTimeout="00:02:00"


                            maxOutboundConnectionsPerEndpoint="100"/>


    </tcpTransport>


  </binding>


</customBinding>





  • .exe.config: For self-host service hosts (not for IIS-hosted services)

<runtime>


  <gcServerenabled="true">


  </gcServer>


</runtime>





  • For ASP.NET Worker Process (single worker process):All options off (worker process recycle off, rapid fail protection off)


  • For Service Implementation use: [ServiceBehavior(ConcurrencyMode= ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerCall)]


  • In .config file for Service –Uses custom WCF behavior to set throttles higher



<behavior name="TradeServiceBehaviors">


  <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>


  <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>


  <serviceThrottling maxConcurrentInstances="400" maxConcurrentCalls="400"/>


</behavior>



Well I hope these Design Decisions and Tuning Parameters will help you Building Interoperable, High-Performance Systems with Windows Communication Foundation (WCF).


 


I discover these great WCF tips when investigating MS "Service-Orientation Case Study" – The .NET StockTrader Application


Yours,


Rotem Bloom

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

8 comments

  1. Shlomi4 באוגוסט 2008 ב 7:40

    For the static WCF channel example – when using multiple threads accessing this channel – how do you manage the close()? when?

    Thanks

    Reply
  2. Rotem Bloom15 באוגוסט 2008 ב 7:39

    Hi Shlomi,
    You can see the property has a SET that is responsible for the closing issue by calling the Abort(), So when you have an exception you are puting NULL on the property and close the proxy. take a look on the SampleCall(string message) function.

    If you need more information write me an email directly or lets talk on the messenger.

    Thanks,
    Rotem

    Reply
  3. Dan30 ביוני 2009 ב 21:26

    Hi,

    many compliments for the post, but just a question: you suggest to turn off the Rapid-Fail protection, but why? which are the drawbacks in leaving it on?

    Reply
  4. Venkat24 ביולי 2009 ב 17:03

    I achive some performance using this article, but on production still my application is slow. how to achive better performance?

    Reply
  5. Rotem Bloom27 ביולי 2009 ב 9:50

    Venkat
    Hi You can contact me directly through my email and I will try to help.

    Reply
  6. Dnana20 בינואר 2010 ב 12:30

    Hi,

    The above code only returns IMyService channel.
    If I want to get different channels IEmailService,
    IAuthenticationService. How I can modify the above code?

    Reply
  7. Dnana20 בינואר 2010 ב 12:30

    Hi,

    The above code only returns IMyService channel.
    If I want to get different channels IEmailService,
    IAuthenticationService. How I can modify the above code?

    Reply
  8. espinete22 בדצמבר 2010 ב 11:18

    any good samples or application with source code in codeplex, msdn, codeproject or another site that uses WCF Achieving High Performance ??

    Thanks.

    Reply