Newbie
Newbie

Reputation: 41

WCF NamedPipes really slow on client side

I am new to WCF and noticed a strange behaviour with a NamedPipes service. The service adds for every service call a custom header with the duration of the service call (server side). The client also measures the time for the service call.

My test service loads about 3000 simple objects from a database. The clients displays those objects in a WPF Grid. While the service side is really fast (about 7ms) the service call in the client takes about 2 seconds. Google told me I should disable security but that didn't help either.

Can you explain why the client call is so slow?

Here is the service function (VB):

Public Function HoleAlleAdressenMitEF() As List(Of Adresse) Implements IDatenbankService.HoleAlleAdressenMitEF
    Dim ergebnis As New List(Of Adresse)
    Dim sw As New Stopwatch
    sw.Start()
    ergebnis = DatenVerzeichnisEF.Instance.HoleAlleAdressen 'loads objects from db
    sw.Stop()

    Dim h As Channels.MessageHeader = Channels.MessageHeader.CreateHeader("Dauer", "ns", sw.Elapsed.ToString)
    OperationContext.Current.OutgoingMessageHeaders.Add(h)

    Return ergebnis
End Function

This is the service call in my client (C#):

        public Adresse[] HoleAlleAdressenMitEF()
        {
            string duration = "0";
            var stopwatch = Stopwatch.StartNew();
            Adresse[] ergebnis;

            using (var scope = new OperationContextScope((IClientChannel)_adressServiceKanal))
            {
                ergebnis = _adressServiceKanal.HoleAlleAdressenMitEF(); //service call
                stopwatch.Stop();
                var headers = OperationContext.Current.IncomingMessageHeaders;
                var header = headers.FindHeader("Dauer", "ns");
                duration = headers.GetHeader<string>(header);
            }


            LetzteAusfuehrDauerGesamt = stopwatch.Elapsed;
            LetzteAusfuehrDauerServerseitig = TimeSpan.Parse(duration);

            return ergebnis;
        }

The last 2 lines before the return store both measures times for later display actions (sorry, german ;) ). And last but not least the binding configuration (C#):

private static void KonfiguriereBindung(NetNamedPipeBinding bindung)
        {
            bindung.TransferMode = TransferMode.Streamed;
            bindung.MaxBufferPoolSize = 2147483647;
            bindung.MaxBufferSize = 2147483647;
            bindung.MaxReceivedMessageSize = 2147483647;
            bindung.ReaderQuotas.MaxArrayLength = 2147483647;
            bindung.ReaderQuotas.MaxBytesPerRead = 2147483647;
            bindung.ReaderQuotas.MaxStringContentLength = 2147483647;
            bindung.ReaderQuotas.MaxDepth = 2147483647;
            bindung.OpenTimeout = TimeSpan.FromMinutes(10);
            bindung.SendTimeout = TimeSpan.FromMinutes(10);
            bindung.ReceiveTimeout = TimeSpan.FromMinutes(10);
            bindung.CloseTimeout = TimeSpan.FromDays(1);
            bindung.Security.Mode = NetNamedPipeSecurityMode.None;
            bindung.Security.Transport = new NamedPipeTransportSecurity() { ProtectionLevel= System.Net.Security.ProtectionLevel.None};
        }

Do I have to add other binding properties? Hope you can help me as I am clueless :)

Upvotes: 1

Views: 178

Answers (1)

Newbie
Newbie

Reputation: 41

Thanks to Larry the client call now needs only 70ms. The delay was the TransferMode.Streaming property. I changed

bindung.TransferMode = TransferMode.Streamed;

to

bindung.TransferMode = TransferMode.Buffered;

and now everything works perfect :) Thanks a lot, Larry! (Why that change didn't work the first time is still a mystery, but I'm not complaining)

Upvotes: 2

Related Questions