Reputation: 41
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
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