Thread not terminating with the application main form closure.

G

Guest

I'm new to C# and threading, so hopefully this is a simple newbie question.

I have a form that is supposed to listen for network traffic on a given port
and decode and display any interesting traffic it sees. To do this I've
launched a separate thread to do the listening.

When I run my form it seems to work fine, but when I close the form the
thread is not being terminated and Task Manager shows the application process
still executing. I tried adding code the the form closing event to abort the
thread, then join it to make sure it was closing properly, and the
application stopped on the join() call, reinforcing that the thread was not
terminating.

Please take pity on a newbie and tell me what I'm I'm doing wrong, or point
me to a good reference. The examples I've seen do no cleanup of the thread,
so I assumed it is supposed to be terminated with the parent application, but
that does not seem to be the case.

The interesting code is:

private void frmMain_Load(object sender, System.EventArgs e)
{
this._ServerIP = new IPEndPoint(IPAddress.Parse
App.Config.DestinationIPAddress), App.Config.DestinationPort);
this._Client = new UdpClient(new IPEndPoint(IPAddress.Any,
App.Config.ListenPort));
this._ListenThread = new Thread(new ThreadStart(RecieveBroadcast));
this._ListenThread.Start();
}

private void RecieveBroadcast()
{
IPEndPoint recieveIP = new IPEndPoint(IPAddress.Any, 0);

while(true)
{
byte[] data = _Client.Receive(ref recieveIP);
}
}
 
N

Nick Hertl

I have seen this before. You have correctly identified the symptoms
and taken the first steps at solving the problem. But there is another
problem...

Socket.Receive() is a blocking call. Once a thread enters this call,
it will not get the opportunity to abort itself until the receive
completes. But what if the socket never receives any more data?
Yah... exacly what you are seeing; your program hangs.

You should probably alter the algorithm that you are using in this
thread to only call Socket.Receive if Socket.Available is greater than
0; This way when you want to abort the thread it will respond.

To demonstrate the difference in behavior, here is a little sample:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

class klass
{
private static Thread t_client;
private static Socket s_client;
private static bool listen;

public static void Main(string[] args)
{
Console.WriteLine("Hello There");
if(args.Length > 0 && args[0] == "listen")
listen = true;
startClient();
Thread.Sleep(2000);
t_client.Abort();
t_client.Join();
}
private static void startClient()
{
s_client = ConnectSocket("www.microsoft.com", 80);
if(listen)
t_client = new Thread(new ThreadStart(listener));
else
t_client = new Thread(new ThreadStart(spinner));
t_client.Start();
}
private static void spinner()
{
while(true)
{
// chose a better time to call Receive only when there is data...
}
}
private static void listener()
{
while(true)
{
byte[] buffer = new byte[256];
int receiveCount = s_client.Receive(buffer);
Console.WriteLine("Received {0} bytes", receiveCount);
}
}
private static Socket ConnectSocket(string server, int port)
{
Socket s = null;
IPHostEntry hostEntry = null;

// Get host related information.
hostEntry = Dns.GetHostEntry(server);

// Loop through the AddressList to obtain the supported
AddressFamily. This is to avoid
// an exception that occurs when the host IP Address is not
compatible with the address family
// (typical in the IPv6 case).
foreach(IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, port);
Socket tempSocket =
new Socket(ipe.AddressFamily, SocketType.Stream,
ProtocolType.Tcp);

tempSocket.Connect(ipe);

if(tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
return s;
}
}
 
G

Guest

I failed to mention that I'm trying to listen for UDP broadcasts and I can't
apparently use your otherwise lovely routine.
 

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