Pukes on 12th invoke

J

Jon Davis

The following code runs fine. I let it go several thousand times and then
killed it.

private void button1_Click(object sender, EventArgs e)
{
int i = 0;
string opOutput = "n/a";
while (true)
{
localpipe.AdminServiceClient client = new
localpipe.AdminServiceClient("pipe");
//opOutput = client.MyOperation1("Yo");
listBox1.Items.Add(DateTime.Now.ToString() + " - " + (i++) + " " +
opOutput);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
listBox1.Invalidate();
Application.DoEvents();
}
}

If I uncomment "opOutput = client.MyOperation1("Yo");", the loop executes 11
times and then everything freezes on the 12th invocation. The method being
invoked is the auto-generated method from the Visual Studio 2005 November
CTP extensions for WCF:

[ServiceContract()]
public interface IAdminService
{
[OperationContract]
string MyOperation1(string myValue);
}

public class AdminService : IAdminService
{
public string MyOperation1(string myValue)
{
return "Hello: " + myValue;
}
}

I tried this over both HTTP and net.pipe. Here is what the listeners are
doing:

internal class AdminServiceHost
{
internal static ServiceHost serviceHost = null;

internal static void StartService()
{
serviceHost = new ServiceHost(typeof(AdminService)); //,
baseAddress);
serviceHost.Open();
}

internal static void StopService()
{
if (serviceHost.State != CommunicationState.Closed)
serviceHost.Close();
}
}

....

<service name="MyApp.AdminService" behaviorConfiguration="returnFaults">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MyApp/"/>
<add baseAddress="net.tcp://localhost:2063/MyApp/"/>
<add baseAddress="net.pipe://localhost/MyApp/"/>
</baseAddresses>
</host>
<endpoint contract="MyApp.IAdminService"
binding="wsHttpBinding"
name="http"
address="Admin" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding"
address="mex" />
<endpoint contract="MyApp.IAdminService"
binding="netTcpBinding"
name="tcp"
address="net.tcp://localhost:2064/MyApp/Admin" />
<endpoint contract="IMetadataExchange" binding="mexTcpBinding"
address="net.tcp://localhost:2063/MyApp/tcpmex" />
<endpoint contract="MyApp.IAdminService"
binding="netNamedPipeBinding"
name="pipe"
address="net.pipe://localhost/MyApp/Admin" />
<endpoint contract="IMetadataExchange" binding="mexNamedPipeBinding"
address="net.pipe://localhost/MyApp/pipemex" />
</service>


The client side is just the auto-generated service reference. I won't bother
pasting that XML here.

Any ideas?

Jon
 
J

Jon Davis

<endpoint contract="MyApp.IAdminService"
binding="netTcpBinding"
name="tcp"
address="net.tcp://localhost:2064/MyApp/Admin" />


... btw please ignore the tcp references. I noticed the ports are mismatched
but I haven't even tried invoking over TCP yet.

Jon
 
J

Jon Davis

(I commented out the TCP listener just to get it out of the way.)

I commented out the while(true) and moved int i=0; to outside the method, so
that it executes once per click. I then clicked on the button quickly, same
results, quickly stalled (this is what I originally did before I moved it to
a loop). I restarted and tried clicking on the button much more slowly, like
one click per second, and it executed 50 times before freezing.

While compiling this post I let it run and got this error message:

System.TimeoutException: The open operation did not complete within the
allotted timeout of 00:01:00. The time allotted to this operation may have
been a portion of a longer timeout. ---> System.TimeoutException: The read
from the pipe did not complete within the allotted timeout of 00:01:00. The
time allotted to this operation may have been a portion of a longer timeout.
at System.ServiceModel.Channels.PipeConnection.WaitForSyncRead(TimeSpan
timeout, Boolean traceExceptionsAsErrors)
at System.ServiceModel.Channels.PipeConnection.Read(Byte[] buffer, Int32
offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer,
Int32 offset, Int32 size, TimeSpan timeout)
at
System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator
upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder,
IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
at
System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection
connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
at
System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection
connection, TimeoutHelper& timeoutHelper)
at
System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan
timeout)
at
System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan
timeout)
--- End of inner exception stack trace ---

Jon
 
J

Jon Davis

Moving localpipe.AdminServiceClient client = new
localpipe.AdminServiceClient("pipe"); to outside the method seems to have
resolved it.

While keeping it outside of this event handler is likely a best practice
anyway, it would seem generating WCF clients is not scalable?! Please tell
me this ain't so!!!

Jon
 
J

Jon Davis

it would seem generating WCF clients is not scalable?! Please tell me this
ain't so!!!

No comments? Our application is an ASP.NET web app that queries an isolated
Windows Service process for indexed data. Keeping a client statically
retained and bottlenecking all queries through it is a serious design
implication--not necessarily horrible, but hampers our options
significantly.

When using SQL Server data connections over named pipes, while it's best
practice to reuse existing connections, it's nice to know that we *can*
instantiate and open relatively unlimited SQL client connections. Is WCF so
non-scalable that it can't handle a tiny handful of connections at a time?

Or is this the result of not hosting the WCF service on IIS 7? I was using a
standalone instance.

Jon
 
J

Jesse Houwing

* Jon Davis wrote, On 19-5-2007 22:14:
No comments? Our application is an ASP.NET web app that queries an isolated
Windows Service process for indexed data. Keeping a client statically
retained and bottlenecking all queries through it is a serious design
implication--not necessarily horrible, but hampers our options
significantly.

When using SQL Server data connections over named pipes, while it's best
practice to reuse existing connections, it's nice to know that we *can*
instantiate and open relatively unlimited SQL client connections. Is WCF so
non-scalable that it can't handle a tiny handful of connections at a time?

Or is this the result of not hosting the WCF service on IIS 7? I was using a
standalone instance.

Normally you can only have 2 open connections to the same webserver at
one time. This is due to the http protocol saying so. I'm not sure if
this is what's working against you, but you can instruct the client to
allow more than two connections to the same host at the same time.

Jesse
 
J

Jon Davis

Jesse Houwing said:
Normally you can only have 2 open connections to the same webserver at one
time. This is due to the http protocol saying so. I'm not sure if this is
what's working against you, but you can instruct the client to allow more
than two connections to the same host at the same time.

I'm using named pipes!!

Jon
 
J

Jon Davis

I'm still getting timeout exceptions, even with Close() being executed (and
I even Thread.Sleep(1) until the State is Closed), when I test with multiple
processes. This thing just plain won't scale.

This might be OS/proc related. On a single-proc workstation using
Win2003SP2, I have six console windows open executing a loop of queries to
the server. Four of the six consoles stall up and one to four eventually die
from timeouts after a few runs. Task Manager reports 247 to 255 Windows
handles in use for each instance. Is that typical of a console app that
opens up a single named pipe connection?

Jon
 
J

Jon Davis

Jon Davis said:
I'm still getting timeout exceptions, even with Close() being executed
(and I even Thread.Sleep(1) until the State is Closed), when I test with
multiple processes. This thing just plain won't scale.

This might be OS/proc related. On a single-proc workstation using
Win2003SP2, I have six console windows open executing a loop of queries to
the server. Four of the six consoles stall up and one to four eventually
die from timeouts after a few runs. Task Manager reports 247 to 255
Windows handles in use for each instance. Is that typical of a console app
that opens up a single named pipe connection?

Yeah this looks like a yielding issue, not WCF-related. Added another
Thread.Sleep() outside of the disposal wait and, although there's still
stalling, there are no more timeouts in my initial test with that change.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top