Asynchronous Sockets and High Async IO Thread Count

G

Guest

Hi there,

Hoping someone could advise me here pls; I'm creating a C# class that
implements a telnet client socket allowing a VB . NET application to
communicate with telnet servers. After leaving the app running for just 6
hrs, the thread count exploded to close to 1000, before the app finally stops
responding. The handles probably hit close to 10000.

Tracing my code, I isolated the leak to when I execute a telnet command.
Everytime I run a telnet command, a thread and several handles are spawned.
After the the command completes, the thread will not die. As I'm unable to
call a EndConnect due to the nature of telnet protocol, could this be giving
me this problem? I tried destroying the telnet client's parent object with a
"Dispose" and "Finalize" and even calling GC, but it still doesn't work out.
The codes attached; hope you can help, thanks!

-------------------------------------------------------------------
public bool Connect()
{
try
{
//connectDone is a ManualResetEvent
connectDone.Reset();

//setup keep-alive heart beats
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive,
10);

//attempt an async connection
s.BeginConnect(iep , callbackProc, s );

//wait for 12 sec until connected to host
for (int count=0; count<24; count++)
{
System.Threading.Thread.Sleep(500);
.....
}

catch(SocketException SockEx) { ... }

catch(Exception NormEx) { ... }
.....
}


private void ConnectCallback( IAsyncResult ar )
{
try
{
// Get The connection socket from the callback
Socket sock1 = (Socket)ar.AsyncState;
if ( sock1.Connected )
{
connectDone.Set();
receiveDone.Reset();

// Define a new Callback to read and handle the data
AsyncCallback receiveData = new AsyncCallback( OnReceivedData )

// Begin reading data asynchronously
sock1.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None,
receiveData , sock1 );
}
}
catch( Exception ex )
{
MessageBox.Show("Setup Receive callbackProc failed!" );
}
}


// This function dispatches a telnet command to the host server
private void SendMessage(string strText)
{
try
{
Byte[] smk = new Byte[strText.Length];

for ( int i=0; i < strText.Length ; i++)
{
//doing telnet stuff ...
}

s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 0);

//*** callbackProc is a new AsyncCallback(ConnectCallback) delegate
sendDone.Reset();
ar2 = s.BeginSend(smk , 0 , smk.Length , SocketFlags.None ,
callbackProc , s );

//check to ensure that async operation has completed
while (ar2 == null || ar2.IsCompleted == false)
{
System.Threading.Thread.Sleep(500);
}

s.EndSend(ar2);
sendDone.Set();
}

catch(Exception ers) { ... }
}
 
P

Peter Bromberg [C# MVP]

Since this is kind of a "non-typical" application, you might want to look
into a custom ThreadPool where you can control more of what is happening
"under the hood".
Stephen Toub of MS has some excellent code in various recent issues of MSDN
Magazine, or you might look at Ami Bar's "SmartThreadPool" over at
codeproject.com
Peter

brendonlam said:
Hi there,

Hoping someone could advise me here pls; I'm creating a C# class that
implements a telnet client socket allowing a VB . NET application to
communicate with telnet servers. After leaving the app running for just 6
hrs, the thread count exploded to close to 1000, before the app finally
stops
responding. The handles probably hit close to 10000.

Tracing my code, I isolated the leak to when I execute a telnet command.
Everytime I run a telnet command, a thread and several handles are
spawned.
After the the command completes, the thread will not die. As I'm unable to
call a EndConnect due to the nature of telnet protocol, could this be
giving
me this problem? I tried destroying the telnet client's parent object with
a
"Dispose" and "Finalize" and even calling GC, but it still doesn't work
out.
The codes attached; hope you can help, thanks!

-------------------------------------------------------------------
public bool Connect()
{
try
{
//connectDone is a ManualResetEvent
connectDone.Reset();

//setup keep-alive heart beats
s.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.KeepAlive,
10);

//attempt an async connection
s.BeginConnect(iep , callbackProc, s );

//wait for 12 sec until connected to host
for (int count=0; count<24; count++)
{
System.Threading.Thread.Sleep(500);
.....
}

catch(SocketException SockEx) { ... }

catch(Exception NormEx) { ... }
.....
}


private void ConnectCallback( IAsyncResult ar )
{
try
{
// Get The connection socket from the callback
Socket sock1 = (Socket)ar.AsyncState;
if ( sock1.Connected )
{
connectDone.Set();
receiveDone.Reset();

// Define a new Callback to read and handle the data
AsyncCallback receiveData = new AsyncCallback( OnReceivedData )

// Begin reading data asynchronously
sock1.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None,
receiveData , sock1 );
}
}
catch( Exception ex )
{
MessageBox.Show("Setup Receive callbackProc failed!" );
}
}


// This function dispatches a telnet command to the host server
private void SendMessage(string strText)
{
try
{
Byte[] smk = new Byte[strText.Length];

for ( int i=0; i < strText.Length ; i++)
{
//doing telnet stuff ...
}

s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay,
0);

//*** callbackProc is a new AsyncCallback(ConnectCallback) delegate
sendDone.Reset();
ar2 = s.BeginSend(smk , 0 , smk.Length , SocketFlags.None ,
callbackProc , s );

//check to ensure that async operation has completed
while (ar2 == null || ar2.IsCompleted == false)
{
System.Threading.Thread.Sleep(500);
}

s.EndSend(ar2);
sendDone.Set();
}

catch(Exception ers) { ... }
}
 
G

Guest

Hi Peter,

Thanks for the references; checked them out, but these were on spinning off
new threads for functions. Any way to do the same when I'm dealing with
asynch socket IO? Thanks

brendon lam

Peter Bromberg said:
Since this is kind of a "non-typical" application, you might want to look
into a custom ThreadPool where you can control more of what is happening
"under the hood".
Stephen Toub of MS has some excellent code in various recent issues of MSDN
Magazine, or you might look at Ami Bar's "SmartThreadPool" over at
codeproject.com
Peter

brendonlam said:
Hi there,

Hoping someone could advise me here pls; I'm creating a C# class that
implements a telnet client socket allowing a VB . NET application to
communicate with telnet servers. After leaving the app running for just 6
hrs, the thread count exploded to close to 1000, before the app finally
stops
responding. The handles probably hit close to 10000.

Tracing my code, I isolated the leak to when I execute a telnet command.
Everytime I run a telnet command, a thread and several handles are
spawned.
After the the command completes, the thread will not die. As I'm unable to
call a EndConnect due to the nature of telnet protocol, could this be
giving
me this problem? I tried destroying the telnet client's parent object with
a
"Dispose" and "Finalize" and even calling GC, but it still doesn't work
out.
The codes attached; hope you can help, thanks!

-------------------------------------------------------------------
public bool Connect()
{
try
{
//connectDone is a ManualResetEvent
connectDone.Reset();

//setup keep-alive heart beats
s.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.KeepAlive,
10);

//attempt an async connection
s.BeginConnect(iep , callbackProc, s );

//wait for 12 sec until connected to host
for (int count=0; count<24; count++)
{
System.Threading.Thread.Sleep(500);
.....
}

catch(SocketException SockEx) { ... }

catch(Exception NormEx) { ... }
.....
}


private void ConnectCallback( IAsyncResult ar )
{
try
{
// Get The connection socket from the callback
Socket sock1 = (Socket)ar.AsyncState;
if ( sock1.Connected )
{
connectDone.Set();
receiveDone.Reset();

// Define a new Callback to read and handle the data
AsyncCallback receiveData = new AsyncCallback( OnReceivedData )

// Begin reading data asynchronously
sock1.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None,
receiveData , sock1 );
}
}
catch( Exception ex )
{
MessageBox.Show("Setup Receive callbackProc failed!" );
}
}


// This function dispatches a telnet command to the host server
private void SendMessage(string strText)
{
try
{
Byte[] smk = new Byte[strText.Length];

for ( int i=0; i < strText.Length ; i++)
{
//doing telnet stuff ...
}

s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay,
0);

//*** callbackProc is a new AsyncCallback(ConnectCallback) delegate
sendDone.Reset();
ar2 = s.BeginSend(smk , 0 , smk.Length , SocketFlags.None ,
callbackProc , s );

//check to ensure that async operation has completed
while (ar2 == null || ar2.IsCompleted == false)
{
System.Threading.Thread.Sleep(500);
}

s.EndSend(ar2);
sendDone.Set();
}

catch(Exception ers) { ... }
}
 

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