Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Out of the box, WCF does not support a service object pool. You need a custom <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstanceprovider.aspx" rel="nofollow">IInstanceProvider</a>. In this scenario the WCF context mode would define when WCF requests a new object from the IInstanceProvider and the IInstanceProvider behavior would manage the pool. Setting the service to either PerInstance or PerSession could make sense depending on the usage. </p> <p>If you are using a Dependency Injection Container in your implementation such as <a href="http://docs.castleproject.org/Windsor.MainPage.ashx" rel="nofollow">Castle Windsor</a>, <a href="http://docs.structuremap.net/" rel="nofollow">StructureMap</a>, or MS Enterprise Library's <a href="http://msdn.microsoft.com/en-us/library/dd203101.aspx" rel="nofollow">Unity</a> then you can use the container's exsiting IInstanceProvider with a pooled lifestyle. All of those containers are reasonable (although I don't personally have much experience with having them manage object pools). </p> <p>My personal choice of container is Castle Windsor. In that case you would use Windsor's <a href="http://docs.castleproject.org/Windsor.WCF-Integration-Facility.ashx" rel="nofollow">WCF Integration Facility</a> and a <a href="http://docs.castleproject.org/Windsor.LifeStyles.ashx#Pooled_10" rel="nofollow">pooled lifestyle</a>.</p> <p>Here's a quick test console program that uses the Castle.Facilites.WcfIntegraion NuGet package. </p> <pre><code>using Castle.Facilities.WcfIntegration; using Castle.MicroKernel.Registration; using Castle.Windsor; using System; using System.Collections.Generic; using System.ServiceModel; using System.Threading.Tasks; namespace WCFWindsorPooledService { [ServiceContract] public interface ISimple { [OperationContract] void Default(string s); } public class SimpleService : ISimple { private static int CurrentIndex = 0; private int myIndex; public SimpleService() { // output which instance handled the call. myIndex = System.Threading.Interlocked.Increment(ref CurrentIndex); } public void Default(string s) { Console.WriteLine("Called #" + myIndex); System.Threading.Thread.Sleep(5); } } class PooledService { static void Main(string[] args) { Console.WriteLine("\n\n" + System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.Name); // define mapping of interfaces to implementation types in Windsor container. IWindsorContainer container = new WindsorContainer(); container.AddFacility&lt;WcfFacility&gt;() .Register(Component.For&lt;SimpleService&gt;().LifeStyle.PooledWithSize(2, 5)); var host = new Castle.Facilities.WcfIntegration.DefaultServiceHostFactory() .CreateServiceHost(typeof(SimpleService).AssemblyQualifiedName, new Uri[] { new Uri("http://localhost/Simple") }); host.Open(); ChannelFactory&lt;ISimple&gt; factory = new ChannelFactory&lt;ISimple&gt;(host.Description.Endpoints[0]); List&lt;Task&gt; tasks = new List&lt;Task&gt;(); for (int i = 0; i &lt; 20; i++) { tasks.Add(Task.Run(() =&gt; { ISimple proxy = factory.CreateChannel(); proxy.Default("Hello"); ((ICommunicationObject)proxy).Shutdown(); })); } Task.WaitAll(tasks.ToArray()); ((ICommunicationObject)host).Shutdown(); container.Dispose(); } } public static class Extensions { static public void Shutdown(this ICommunicationObject obj) { try { obj.Close(); } catch (Exception ex) { Console.WriteLine("Shutdown exception: {0}", ex.Message); obj.Abort(); } } } } </code></pre> <p>I'm not going to pretend to understand all the rules of how Castle manages a pool, but a pool is clearly being used. The output is:</p> <pre><code>PooledService Called #1 Called #5 Called #2 Called #3 Called #4 Called #6 Called #7 Called #8 Called #7 Called #4 Called #2 Called #5 Called #1 Called #10 Called #6 Called #9 Called #4 Called #7 Called #1 Called #9 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload