Thread Problem

29/11/2006 - 18:39 por JC | Informe spam
Hi People,

Please I need your help.

This code run a thread ok but Not close later.

thanks...

private void RunServer(int aPortNumber)
{
_listener = new TcpListener(IPAddress.Any, aPortNumber);
_listener.Start();

_ServerThread = new Thread(delegate()
{
AcceptClients();
}
);
_ServerThread.Start();
}

public void Close()
{

_ThreadRun = false;

}


public void AcceptClients()
{
while (_ThreadRun)
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);

..
}

}

Preguntas similare

Leer las respuestas

#1 Dave Sexton
29/11/2006 - 19:56 | Informe spam
Hi,

That is because _listener.AcceptTcpClient() is blocking the thread. Setting
_ThreadRun to false isn't going to do anything until
_listener.AcceptTcpClient() returns.

Since there doesn't seem to be any error handling code in place, you won't
be able to end the background thread gracefully. Calling _listener.Stop()
will close the listener, causing AcceptTcpClient to stop blocking, however
an exception will be thrown. Setting _ThreadRun would be pointless in that
case, although it's possible that setting _ThreadRun may cause the loop to
exit if it's set after _listener.AcceptTcpClient() returns and before the
loop restarts, but you shouldn't count on that.

Try the following code instead:

while (true)
{
try
{
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);
}
}
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.Interrupted)
return;
else
throw;
}
}

Dave Sexton

"JC" wrote in message
news:
Hi People,

Please I need your help.

This code run a thread ok but Not close later.

thanks...

private void RunServer(int aPortNumber)
{
_listener = new TcpListener(IPAddress.Any, aPortNumber);
_listener.Start();

_ServerThread = new Thread(delegate()
{
AcceptClients();
}
);
_ServerThread.Start();
}

public void Close()
{

_ThreadRun = false;

}


public void AcceptClients()
{
while (_ThreadRun)
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);

..
}

}

Respuesta Responder a este mensaje
#2 ThunderMusic
29/11/2006 - 20:08 | Informe spam
hi,

I've always learned that relying on exception as a normal process is bad
practice when there is another way to go. And in this case, there is another
way to go : BeginAcceptTcpClient(...) Just call
_listener.BeginAcceptTcpClient(...) and everything will be fine... ;) if
you need help using it, go there :

http://msdn2.microsoft.com/en-us/li...lient.aspx

I hope it helps

ThunderMusic

"Dave Sexton" [remove.this]online.com> wrote in message
news:uCQ5Zg%
Hi,

That is because _listener.AcceptTcpClient() is blocking the thread.
Setting _ThreadRun to false isn't going to do anything until
_listener.AcceptTcpClient() returns.

Since there doesn't seem to be any error handling code in place, you won't
be able to end the background thread gracefully. Calling _listener.Stop()
will close the listener, causing AcceptTcpClient to stop blocking, however
an exception will be thrown. Setting _ThreadRun would be pointless in
that case, although it's possible that setting _ThreadRun may cause the
loop to exit if it's set after _listener.AcceptTcpClient() returns and
before the loop restarts, but you shouldn't count on that.

Try the following code instead:

while (true)
{
try
{
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);
}
}
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.Interrupted)
return;
else
throw;
}
}

Dave Sexton

"JC" wrote in message
news:
Hi People,

Please I need your help.

This code run a thread ok but Not close later.

thanks...

private void RunServer(int aPortNumber)
{
_listener = new TcpListener(IPAddress.Any, aPortNumber);
_listener.Start();

_ServerThread = new Thread(delegate()
{
AcceptClients();
}
);
_ServerThread.Start();
}

public void Close()
{

_ThreadRun = false;

}


public void AcceptClients()
{
while (_ThreadRun)
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);

..
}

}





Respuesta Responder a este mensaje
#3 Dave Sexton
29/11/2006 - 20:21 | Informe spam
Hi,

I've always learned that relying on exception as a normal process is bad
practice when there is another way to go



If the code is going to work reliably then exception handling is a must, so
there is no harm in simply returning in the case of an exception that can be
handled.

And in this case, there is another way to go : BeginAcceptTcpClient(...)
Just call _listener.BeginAcceptTcpClient(...) and everything will be
fine... ;)



<snip>

BeginAcceptTcpClient will not help here.

The loop still has to block somehow, and if you call _listener.Stop() an
exception will still be thrown even though Begin* is called.

IAsyncResult result = _listener.BeginAcceptTcpClient(null, null);

// now, we're just blocking here instead of there ^
using (TcpClient client = _listener.EndAcceptTcpClient(result))
{
...
}

You could have a sub-loop that checks an EventWaitHandle and a variable such
as _ThreadRun, as in the OP, but the code will become more complex with no
real gain. And, exception handling code should still be implemented anyway.

Dave Sexton
Respuesta Responder a este mensaje
#4 Brian Gideon
29/11/2006 - 20:28 | Informe spam
JC,

Like Dave said TcpListener.AcceptTcpClient is your biggest problem.
But, even if you fix that the subtle memory barrier problem with
_ThreadRun still exists. You should wrap reads and writes to
_ThreadRun with a lock to ensure changes to it are visible in all
threads.

Brian

JC wrote:
Hi People,

Please I need your help.

This code run a thread ok but Not close later.

thanks...

private void RunServer(int aPortNumber)
{
_listener = new TcpListener(IPAddress.Any, aPortNumber);
_listener.Start();

_ServerThread = new Thread(delegate()
{
AcceptClients();
}
);
_ServerThread.Start();
}

public void Close()
{

_ThreadRun = false;

}


public void AcceptClients()
{
while (_ThreadRun)
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);

..
}

}
Respuesta Responder a este mensaje
#5 Brian Gideon
29/11/2006 - 21:01 | Informe spam
JC,

Like Dave said TcpListener.AcceptTcpClient is your biggest problem.
But, even if you fix that the subtle memory barrier problem with
_ThreadRun still exists. You should wrap reads and writes to
_ThreadRun with a lock to ensure changes to it are visible in all
threads.

Brian

JC wrote:
Hi People,

Please I need your help.

This code run a thread ok but Not close later.

thanks...

private void RunServer(int aPortNumber)
{
_listener = new TcpListener(IPAddress.Any, aPortNumber);
_listener.Start();

_ServerThread = new Thread(delegate()
{
AcceptClients();
}
);
_ServerThread.Start();
}

public void Close()
{

_ThreadRun = false;

}


public void AcceptClients()
{
while (_ThreadRun)
using (TcpClient client = _listener.AcceptTcpClient())
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
stream.Read(data, 0, data.Length);
string request = Encoding.ASCII.GetString(data);

..
}

}
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida