Tobias Moe Thorstensen
Tobias Moe Thorstensen

Reputation: 8981

WCF Instance mode and inactivityTimeout

How does the WCF Instance mode relate to the inactivityTimeout in WCF? Let's say I have this binding in my web.config:

<wsHttpBinding>
 <binding name="WSHttpBinding" receiveTimeout="infinite">
   <reliableSession inactivityTimeout="infinite" enabled="true" />
 </binding>
</wsHttpBinding>

How does WCF instance modes, PerCall, PerSession, Single relate to this timeout? Lets say I attributed my service with PerCall, will this inactivityTimeout only be valid in the timespan where I do the service call, and close the connection or will it stays open "forever"?

Upvotes: 0

Views: 287

Answers (1)

Lawrence
Lawrence

Reputation: 3297

I found the test below useful for investigating your problem. In summary, it seems instance mode of the service has no bearing whatsoever on the inactivity timeout. The inactivity timeout concerns how long the underlying channel is inactive for before the server will refuse any request from it.

[TestClass]
public class Timeouts
{
    [TestMethod]
    public void Test()
    {
        Task.Factory.StartNew(() =>
        {
            var serverBinding = new NetTcpBinding();
            serverBinding.ReliableSession.Enabled = true;
            serverBinding.ReliableSession.InactivityTimeout = TimeSpan.FromSeconds(4);
            var host = new ServiceHost(typeof (MyService));
            host.AddServiceEndpoint(typeof (IMyService), serverBinding, "net.tcp://localhost:1234/service");
            host.Open();
        }).Wait();

        var clientBinding = new NetTcpBinding();
        clientBinding.ReliableSession.Enabled = true;

        var channelFactory = new ChannelFactory<IMyService>(clientBinding, "net.tcp://localhost:1234/service");

        var channelOne = channelFactory.CreateChannel();

        channelOne.MyMethod();
        Thread.Sleep(TimeSpan.FromSeconds(3));
        channelOne.MyMethod();

        (channelOne as ICommunicationObject).Close();

        Thread.Sleep(TimeSpan.FromSeconds(5));

        var channelTwo = channelFactory.CreateChannel();

        channelTwo.MyMethod();
        Thread.Sleep(TimeSpan.FromSeconds(6));
        channelTwo.MyMethod();

        (channelTwo as ICommunicationObject).Close();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MyService : IMyService
    {
        public void MyMethod()
        {
            Console.WriteLine("Hash: " + GetHashCode());
            Console.WriteLine("Session: " + OperationContext.Current.SessionId);
            Console.WriteLine();
        }
    }

    [ServiceContract]
    public interface IMyService
    {
        [OperationContract]
        void MyMethod();
    }
}

I think this just underlines how important it is to always close your clients to WCF proxies. If you do not close your proxy, with a inactivity timeout of "infinite" you may well end up using resources on the server well after you are done with your proxy.

Upvotes: 1

Related Questions