tags:

views:

121

answers:

1

Hi , I am trying to build a DAL for Oracle using WCF.My Application is on intranet,So i choose to go for tcp binding which is supposed to be fastest. My requirment is simple. My DAL exposes function which returns dataset based on query/sp. Initially we used webservice and everything was fine except timeout problems. Some of the SP request take more than 2hrs to complete and WCF run smoothely...no timeouts if you set parameter right :)

Problem came when we made it live and more than 150 users acces it simultaneoulsy. I researched and found that i was not closing proxy.So I did that and scenario improved but performace is still only 50% of webservice and at time user is not able to connect at all.

Now lot of article and lot of suggestiions I went through and Most typical answer is it depended on your requirments how to set parameters(they are so many ... :( ).

Somebody will pls help me with the suggestion given my specific requirments. Long calls are only 10 %(those consuming 2-3 hrs ) .

My service is hosted in window service.Pls see this following lines:

namespace Phoenix { partial class PhoenixDataServiceHost : ServiceBase { public PhoenixDataServiceHost() { InitializeComponent(); }

    internal static ServiceHost svh;
    string IpPort = "8043";
    protected override void OnStart(string[] args)
    {
        NetTcpBinding ntcp = new NetTcpBinding();

        ntcp.Security.Mode = SecurityMode.None;
        ntcp.MaxBufferPoolSize = 2147483647;
        ntcp.MaxReceivedMessageSize = 2147483647;
        ntcp.MaxBufferSize = 2147483647;
        ntcp.ReaderQuotas.MaxStringContentLength = 2147483647;
        ntcp.ReaderQuotas.MaxDepth = 2147483647;
        ntcp.ReaderQuotas.MaxBytesPerRead = 2147483647;
        ntcp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
        ntcp.ReaderQuotas.MaxArrayLength = 2147483647;
        ntcp.SendTimeout = new TimeSpan(3, 0, 0);
        ntcp.ReceiveTimeout = new TimeSpan(3, 0, 0);
        ntcp.OpenTimeout = new TimeSpan(0, 10, 0);
        ntcp.CloseTimeout = new TimeSpan(0, 10, 0);
        ntcp.MaxConnections = 400;
        ntcp.ListenBacklog = 500;

        if (svh != null)
        {
            svh.Close();
        }
        svh = new ServiceHost(typeof(PhoenixDataService));
        ((ServiceBehaviorAttribute)svh.Description.Behaviors[0]).MaxItemsInObjectGraph = 2147483647;
        ((ServiceBehaviorAttribute)svh.Description.Behaviors[0]).IncludeExceptionDetailInFaults = true;
        svh.AddServiceEndpoint(
            typeof(IPhoenixDataLayer),
            ntcp,
            "net.tcp://localhost:"+IpPort);
        System.ServiceModel.Description.ServiceThrottlingBehavior throttlingBehavior =
 new System.ServiceModel.Description.ServiceThrottlingBehavior();
        throttlingBehavior.MaxConcurrentCalls = 400;
        throttlingBehavior.MaxConcurrentInstances = Int32.MaxValue;
        throttlingBehavior.MaxConcurrentSessions = 400;
        svh.Description.Behaviors.Add(throttlingBehavior); 
        svh.Open();
    }

    protected override void OnStop()
    {
        if (svh != null)
        {
            svh.Close();
        }
    }
}

}

I am using channel factory on client. pls find code below:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Phoenix; using System.ServiceModel; using System.Data; using CustomEnum; namespace KIPLProject { public class PhoenixDataServerProxy { static ChannelFactory scf; static IPhoenixDataLayer client;

    public void OpenChannel()
    {
        //  client = new PhoenixDataService();
        //  return;

        //if (scf == null)
        //{
            NetTcpBinding ntcp = new NetTcpBinding();

            ntcp.MaxBufferPoolSize = 2147483647;
            ntcp.MaxReceivedMessageSize = 2147483647;
            ntcp.MaxBufferSize = 2147483647;
            ntcp.ReaderQuotas.MaxStringContentLength = 2147483647;
            ntcp.ReaderQuotas.MaxDepth = 2147483647;
            ntcp.ReaderQuotas.MaxBytesPerRead = 2147483647;
            ntcp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
            ntcp.ReaderQuotas.MaxArrayLength = 2147483647;
            ntcp.SendTimeout = new TimeSpan(3, 0, 0);
            ntcp.ReceiveTimeout = new TimeSpan(3, 0, 0);
            ntcp.OpenTimeout = new TimeSpan(0, 2, 0);
            ntcp.CloseTimeout = new TimeSpan(0, 10, 0);
            ntcp.Security.Mode = SecurityMode.None;
            scf = new ChannelFactory<IPhoenixDataLayer>(ntcp, "net.tcp://"+Program.wcfPort);

            client = scf.CreateChannel();

       // }



    }

    public PhoenixDataServerProxy(string Name, KIPLCommandType Type)
    {
        SPName = Name;
        SPType = Type.ToString();
        Index = 0;
    }

    public PhoenixDataServerProxy()
    {
        Index = 0;

    }


    #region proxy for WCF Service Function
    public DataSet GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode)
    {
        try
        {
            OpenChannel();
            DataSet ds = client.GetDataSet(Param, SpName, Type, constr, DebugMode);
            CloseChannel();
            return ds;

        }
        catch (Exception)
        {

            scf = null;
            return null;
        }
    }

}

Now My Application is already live and shutdown of service is a big issue so i am restriced with too many experiments. PLs suggest if I need to set parameters differently

A: 

You are using a single client for all requests. This may be what is causing you problems.

What you could do is to create a new client proxy for each request. Create it with the "using" statement to make sure that it is properly cleaned up / disposed.

On the client side first create a proxy class:

public class PhoenixDataLayerProxy : ClientBase<IPhoenixDataLayer>, IPhoenixDataLayer
{
    public DataSet GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode)
    {
        return base.Channel.GetDataSet(string[][] Param, string SpName, string Type, string constr, bool DebugMode);
    }

}

Then use the proxy in a using statement:

using (PhoenixDataLayerProxy client = new PhoenixDataLayerProxy() { var result = client.GetDataSet ..... }

It may also be that you are hitting the limit for max Inbound Connections. See:

http://blogs.msdn.com/drnick/archive/2006/03/10/547568.aspx

Shiraz Bhaiji
Sorry,didnt get your point. Can you pls point out in my code what you meant to say!!!!!
Actually in forums I got the point that we should cache proxy object as channel creation is costly.My Clients anyways will create a separate request as its a wpf application;so would this change work?? Sorry to bother but I need to be sure before I do this change as service is already live