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

#6 Hernando Gisinger
29/11/2006 - 21:10 | Informe spam
Yo creo que todos tienen razón. También creo que deberían dejar de
escribir en inglés en un newsgroup en castellano.

Gracias.

Brian Gideon escribió:
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
#7 Dave Sexton
29/11/2006 - 21:16 | Informe spam
Hi Brian,

Good point about volatility, however the variable is pointless anyway. It
won't allow the OP to control the background thread.

The only way to stop the _listener.AcceptTcpClient method from blocking is
to call _listener.Stop(), which will cause an exception to be thrown and the
variable won't be checked.

BeginAcceptTcpClient cannot be stopped gracefully either. Calling
_listener.Stop() will cause an exception to be thrown as well.

The OP should write code to handle this exception and exit the background
thread, as in my example.

Dave Sexton

"Brian Gideon" wrote in message
news:
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
#8 ThunderMusic
29/11/2006 - 21:43 | Informe spam
yes, exception handling is a must to handle exceptional situations, but the
process should never be based on exception handling as you are advising
here... and yes there is harm because exception handling is very costy
resource-wise, so if you can avoid it, avoid it...

I really think you should read on asynchronous programming, it would really
help... I've done this kind of processing many times using
BeginAcceptTcpClient(...) without any problem when stopping my apps... I
don't have sample code at hand, but I know it worked fine... follow the
link I provided and you will most likely find what you need...

I hope it helps

ThunderMusic



"Dave Sexton" [remove.this]online.com> wrote in message
news:%23XbvSu%
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
#9 Dave Sexton
29/11/2006 - 22:09 | Informe spam
Hi,

yes, exception handling is a must to handle exceptional situations, but
the process should never be based on exception handling as you are
advising here... and yes there is harm because exception handling is very
costy resource-wise, so if you can avoid it, avoid it...



Your recommendation works great for control-of-flow on a single thread (e.g,
don't use exceptions to control flow :), but it doesn't apply in this
situation.

My code doesn't process based on exceptions, it handles a situation that
cannot be avoided in a way that will perform better or be easier to read,
IMO. I'd much rather have the I/O completion thread block instead of
spinning a thread for an arbitrary number of milliseconds to periodically
check a wait handle or check a volatile variable, or having to lock and
unlock an object.

The exception will only be thrown once, indeterminately, so it is an
exceptional circumstance.

If the OP is planning on starting and stopping the listener repeatedly than
I might agree that a different solution would be in order, however I assume
that isn't the case.

The code is clean and should perform exceptionally well. (no pun intended
:)

I really think you should read on asynchronous programming, it would
really help... I've done this kind of processing many times using
BeginAcceptTcpClient(...) without any problem when stopping my apps... I
don't have sample code at hand, but I know it worked fine... follow the
link I provided and you will most likely find what you need...



I can assure you that a SocketException is thrown by the
EndAcceptTcpClient() method when you stop the listener on another thread.

In the 1.* frameworks you wouldn't have known there was an exception being
thrown when you disposed of the listener, while it was being used on a
background thread, so that might have been your problem.

Also, it doesn't make sense to use a ThreadPool thread from a background
thread in this scenario. It's just asking for dead locks in a service
application.

Dave Sexton
Respuesta Responder a este mensaje
#10 JC
29/11/2006 - 22:37 | Informe spam
Thanks...
I'm ready...

"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
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida