473,487 Members | 2,467 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

tcpLisetener + Thread problem

Hello there,

Lets say I have something like this in my Mother Of All Threads:

Thread thread1 = new Thread(new ThreadStart(this.run));
thread1.Start();
//some unimportant code
thread1.Abort();
thread1.Join();

And in thread1 I have:

try {
tcpListener = new TcpListener(this.port);
tcpListener.Start();
tcpClient = tcpListener.AcceptTcpClient();
//more unimportant code
} catch (ThreadAbortException) {
tcpClient.Stop();
//not sure whether I need the line above, but that's not the problem
anyway
tcpListener.Stop();
}

What happens now is thread1 gets started, gets to the
"tcpListener.AcceptTcpClient()" call and waits for a client to connect.
In
the mean time Mother Of All Threads gets to the "thread1.Abort()" and
raises the ThreadAbortException... and nothing happens. tcpListener
still
hangs and waits for the connection, and blocks the ThreadAbortException
from occuring! Now, shouldn't that be impossible? I was taught to firmly
believe in the Almighty Exception... something's very wrong here...
would
somebody enlighten me, please! :-)

BTW, yes, I know, I could make a socket which will connect to the server
and unblock the Listener, but that's a dirty and ugly hack. There should
be some elegant solution for interupting tcpListener... shouldn't it?

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"
Nov 16 '05 #1
10 10338
The tcp listener calls accept on a socket object which in turn calls out to
a native method using P/Invoke.

I would imagine that the exception don't travel to the native method and
therefore the thread wont be aborted. I've experienced similar behaviour
with SqlDataAdapter.Fill but never found the solution..

--
Patrik Löwendahl [C# MVP]
www.cshrp.net - "Elegant code by witty programmers"
"Nikola Skoric" <ni*******@net4u.hr> wrote in message
news:MPG.1bd38843429e2d1989950@localhost...
Hello there,

Lets say I have something like this in my Mother Of All Threads:

Thread thread1 = new Thread(new ThreadStart(this.run));
thread1.Start();
//some unimportant code
thread1.Abort();
thread1.Join();

And in thread1 I have:

try {
tcpListener = new TcpListener(this.port);
tcpListener.Start();
tcpClient = tcpListener.AcceptTcpClient();
//more unimportant code
} catch (ThreadAbortException) {
tcpClient.Stop();
//not sure whether I need the line above, but that's not the problem
anyway
tcpListener.Stop();
}

What happens now is thread1 gets started, gets to the
"tcpListener.AcceptTcpClient()" call and waits for a client to connect.
In
the mean time Mother Of All Threads gets to the "thread1.Abort()" and
raises the ThreadAbortException... and nothing happens. tcpListener
still
hangs and waits for the connection, and blocks the ThreadAbortException
from occuring! Now, shouldn't that be impossible? I was taught to firmly
believe in the Almighty Exception... something's very wrong here...
would
somebody enlighten me, please! :-)

BTW, yes, I know, I could make a socket which will connect to the server
and unblock the Listener, but that's a dirty and ugly hack. There should
be some elegant solution for interupting tcpListener... shouldn't it?

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"

Nov 16 '05 #2
I've dug around for a bit.

There's a stop method on the TcpListener class. The stop method closes and
throws away the underlying socket. Try calling Stop on the listener instead
of abort the thread.

Another way is to kill the thread is to use the API TerminateThread but that
is a potential catastrophy since you wouldn't know what resources the native
code has opened and won't have the chance to close or release.

The third solution is probably a total overkill, you could let the thread
run in a separate appdomain and unload the appdomin itself, this might
terminate the thread but you have no guarantee.

--
Patrik Löwendahl [C# MVP]
www.cshrp.net - "Elegant code by witty programmers"

"Nikola Skoric" <ni*******@net4u.hr> wrote in message
news:MPG.1bd38843429e2d1989950@localhost...
Hello there,

Lets say I have something like this in my Mother Of All Threads:

Thread thread1 = new Thread(new ThreadStart(this.run));
thread1.Start();
//some unimportant code
thread1.Abort();
thread1.Join();

And in thread1 I have:

try {
tcpListener = new TcpListener(this.port);
tcpListener.Start();
tcpClient = tcpListener.AcceptTcpClient();
//more unimportant code
} catch (ThreadAbortException) {
tcpClient.Stop();
//not sure whether I need the line above, but that's not the problem
anyway
tcpListener.Stop();
}

What happens now is thread1 gets started, gets to the
"tcpListener.AcceptTcpClient()" call and waits for a client to connect.
In
the mean time Mother Of All Threads gets to the "thread1.Abort()" and
raises the ThreadAbortException... and nothing happens. tcpListener
still
hangs and waits for the connection, and blocks the ThreadAbortException
from occuring! Now, shouldn't that be impossible? I was taught to firmly
believe in the Almighty Exception... something's very wrong here...
would
somebody enlighten me, please! :-)

BTW, yes, I know, I could make a socket which will connect to the server
and unblock the Listener, but that's a dirty and ugly hack. There should
be some elegant solution for interupting tcpListener... shouldn't it?

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"

Nov 16 '05 #3
"Nikola Skoric" <ni*******@net4u.hr> wrote in message
news:MPG.1bd38843429e2d1989950@localhost...
Hello there,

Lets say I have something like this in my Mother Of All Threads:

Thread thread1 = new Thread(new ThreadStart(this.run));
thread1.Start();
//some unimportant code
thread1.Abort();
thread1.Join();

And in thread1 I have:

try {
tcpListener = new TcpListener(this.port);
tcpListener.Start();
tcpClient = tcpListener.AcceptTcpClient();
//more unimportant code
} catch (ThreadAbortException) {
tcpClient.Stop();
//not sure whether I need the line above, but that's not the problem
anyway
tcpListener.Stop();
}

What happens now is thread1 gets started, gets to the
"tcpListener.AcceptTcpClient()" call and waits for a client to connect.
In
the mean time Mother Of All Threads gets to the "thread1.Abort()" and
raises the ThreadAbortException... and nothing happens. tcpListener
still
hangs and waits for the connection, and blocks the ThreadAbortException
from occuring! Now, shouldn't that be impossible? I was taught to firmly
believe in the Almighty Exception... something's very wrong here...
would
somebody enlighten me, please! :-)

BTW, yes, I know, I could make a socket which will connect to the server
and unblock the Listener, but that's a dirty and ugly hack. There should
be some elegant solution for interupting tcpListener... shouldn't it?


I don't know why the ThreadAbortException doesn't work (though maybe it's
related to the problem discussed in
news:Ou**************@TK2MSFTNGP12.phx.gbl), but the method I use to abort
the TcpListener is to call tcpListener.Stop() from the main thread (i.e.
from your Mother Of All Threads). This raises a SocketException in the
listening thread (your thread1). I'm not sure whether this is 100% safe,
since calling a method of the TcpListener from a different thread than the
one it was created on may lead to some nasty race condition - but AFAIK it's
never gone wrong in practice.

Chris Jobson
Nov 16 '05 #4
Dana Sun, 10 Oct 2004 18:56:55 +0200
Nikola Skoric (ni*******@net4u.hr) kaze...
Hello there,

Lets say I have something like this in my Mother Of All Threads: /snip would
somebody enlighten me, please! :-)


Ahhhhhhhhhhhhhh! Found the soution (although I still lack the
explanation of Exception blocking "feature"). I just put this:

while (!tcpListener.Pending()) Thread.Sleep(500);

before this:

tcpClient = tcpListener.AcceptTcpClient();

Now the Exception is handled and everthing goes fine.

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"
Nov 16 '05 #5
> while (!tcpListener.Pending()) Thread.Sleep(500);

Hi Nikola. This is not a great solution for a couple reasons. One is that
clients will have to wait 0-500ms to connect, so your forcing an artificial
connect slowdown. Second, your introducing a spin for no reason. When not
clients connect, your spinning forever which wastes cpu time and on a laptop
or other small device would drain the battery as it would not allow cpu to
go into low power state. Below is simple server implementation that allows
you to block until connect and also allows you to shutdown. You still throw
a socket exception when stopping the listener as it is in blocking mode, but
that is ok as we expect it and catch it before shutting down.

/// <summary>
/// Server listens and writes files to disk.
/// </summary>
public sealed class SimpleServer
{

private readonly Thread thread;
private readonly TcpListener listener;
private bool stopped = true;
private readonly object syncRoot;

public SimpleServer(IPAddress listenIP, int port)
{
if ( listenIP == null )
throw new ArgumentNullException();
syncRoot = new object();
listener = new TcpListener(listenIP, port);
thread = new Thread(new ThreadStart(ServerStart));
thread.Name = "Listener";
}

public bool IsStopped
{
get
{
lock(syncRoot)
{
return stopped;
}
}
}

public bool IsStarted
{
get
{
lock(syncRoot)
{
return ! stopped;
}
}
}

public void Start()
{
lock(syncRoot)
{
if ( stopped )
{
stopped = false;
thread.Start();
}
}
}

public void Stop()
{
lock(syncRoot)
{
if ( stopped )
return;
stopped = true;
listener.Stop();
}
}

private void ServerStart()
{
try
{
listener.Start();
Console.WriteLine("Listing on: "+listener.LocalEndpoint.ToString());
while( IsStarted )
{
// Wait for a client to connect.
Console.WriteLine("Waiting for a client to connect.");
Socket socket = listener.AcceptSocket();
if ( IsStopped )
break;
Console.WriteLine("Client Connected: " +
socket.RemoteEndPoint.ToString());

// Create and start client worker.
ClientWorker cw = new ClientWorker(socket);
cw.Start(); // Starts the worker which also starts it's thread.
}
}
catch(SocketException se)
{
// Calling listen.Stop() while Listening will throw
// "A blocking operation was interrupted by a call to
WSACancelBlockingCall".
Console.WriteLine("Server Socket Exception: " + se.Message);
}
catch(Exception ex)
{
Console.WriteLine("Server Exception: " + ex.Message);
}
finally
{
try
{
Stop();
Console.WriteLine("Server Stopped.");
}
catch
{
}
}
}
}

Nov 16 '05 #6
Dana Sun, 10 Oct 2004 19:43:58 -0400
William Stacey [MVP] (st***********@mvps.org) kaze...
while (!tcpListener.Pending()) Thread.Sleep(500);
Hi Nikola. This is not a great solution for a couple reasons. One is that
clients will have to wait 0-500ms to connect, so your forcing an artificial
connect slowdown. Second, your introducing a spin for no reason. When not
clients connect, your spinning forever which wastes cpu time and on a laptop
or other small device would drain the battery as it would not allow cpu to
go into low power state. Below is simple server implementation that allows
you to block until connect and also allows you to shutdown. You still throw
a socket exception when stopping the listener as it is in blocking mode, but
that is ok as we expect it and catch it before shutting down.


Thank you for explanation. It is most kind of you. I read this code and
it introduced a number of nice tricks I'll use. Somehow I thought I
shouldn't access objects instanced inside of some other thread... but I
don't remember anyone mentioning that explicitly... just my imagination
then :-)
public bool IsStopped
{
get
{
lock(syncRoot)
{
return stopped;
}
}
}
Say, why not "lock(stopped)"? Why do you need syncRoot?
public sealed class SimpleServer


And, why sealing the class? Is it you just have a practise of sealing
everthing you can (now, why would you do that?) or do you have a reason
you sealed this one?

Thank you again, you gave me some nice ideas.

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"
Nov 16 '05 #7
Nikola Skoric <ni*******@net4u.hr> wrote:
Thank you for explanation. It is most kind of you. I read this code and
it introduced a number of nice tricks I'll use. Somehow I thought I
shouldn't access objects instanced inside of some other thread... but I
don't remember anyone mentioning that explicitly... just my imagination
then :-)
public bool IsStopped
{
get
{
lock(syncRoot)
{
return stopped;
}
}
}


Say, why not "lock(stopped)"? Why do you need syncRoot?


Because stopped is a boolean. Value types don't have associated
monitors.
public sealed class SimpleServer


And, why sealing the class? Is it you just have a practise of sealing
everthing you can (now, why would you do that?) or do you have a reason
you sealed this one?


Sealing classes that aren't specifically designed to be derived from is
good practice, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8
Dana Mon, 11 Oct 2004 09:23:20 +0100
Jon Skeet [C# MVP] (sk***@pobox.com) kaze...
Nikola Skoric <ni*******@net4u.hr> wrote:

/snip
Say, why not "lock(stopped)"? Why do you need syncRoot?


Because stopped is a boolean. Value types don't have associated
monitors.


Thanks!

--
"Stara boljka se leci starim lekom...
Dabome vinom, ta nebi valjda mlekom?"
Nov 16 '05 #9
On Sun, 10 Oct 2004 19:43:58 -0400, William Stacey [MVP] wrote:
Socket socket = listener.AcceptSocket();
if ( IsStopped )
break;


Problem here is that if there's no client and no blocking timeout, the
server keeps listening for an indefinite amount of time. So is this really
a solution?

Also, since the thread isn't a background thread (Thread.IsBackground),
this application, as is, won't terminate on its own under certain
conditions.
Nov 16 '05 #10
On Sat, 9 Oct 2004 15:32:28 +0100, C# Learner wrote:
Problem here is that if there's no client and no blocking timeout, the
server keeps listening for an indefinite amount of time. So is this really
a solution?

Also, since the thread isn't a background thread (Thread.IsBackground),
this application, as is, won't terminate on its own under certain
conditions.


Sorry -- I inadvertently skipped over TcpListener.Stop call.
Nov 16 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
375
by: Steven Brown | last post by:
I'm trying to figure out how to safely use .NET events/delegates in a thread-safe class. There are a couple problems. One is that the standard "if(EventName != null) EventName(...);" call can...
6
2315
by: Tony Proctor | last post by:
Hi everyone We're experiencing some serious anomalies with the scheduling of ASP threads. I'd be interested to hear if anyone knows what algorithm is used (e.g. simple round-robin, or something...
7
2681
by: Ivan | last post by:
Hi I have following problem: I'm creating two threads who are performing some tasks. When one thread finished I would like to restart her again (e.g. new job). Following example demonstrates...
20
2988
by: Doug Thews | last post by:
I ran into an interesting re-pain delay after calling the Abort() method on a thread, but it only happens the very first time I call it. Every time afterward, there is no delay. I've got a...
4
6191
by: Madhu Gopinathan | last post by:
Hi All, I am faced with a horrible hang problem. I have a COM exe server that executes some tasks. The task execution manager is a thread that manages the pool of threads, which is 4 per processor....
0
2042
by: Shoveler | last post by:
I've got an odd problem here that I've been beating my head on for days. I've written a class that uses a pre-established connection for communication, meaning I can use this class for a server or...
0
1159
by: David | last post by:
I've written a small windows service, and I'm having a problem that I'm spending a lot more time on than I'd like. If anyone has experienced this problem and has any hints or solutions; they would...
14
2893
by: Christian Kaiser | last post by:
We have a component that has no window. Well, no window in managed code - it uses a DLL which itself uses a window, and this is our problem! When the garbage collector runs and removes our...
10
2515
by: Bryce Calhoun | last post by:
Hello, First of all, this is a .NET 1.1 component I'm creating. SUMMARY ----------------------- This component that I'm creating is, for all intents and purposes, a document parser (I'm...
0
7105
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6967
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7132
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6846
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7341
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4870
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3076
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1381
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
600
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.