Before posting a bug report please verify this too.
The following code behaves differently on 4.1.x and 4.2b1. (Make sure the ip doesn't exist on your LAN or that the ethernet is not connected)
static void Main()
{
new Thread(BlinkStatusLed).Start();
new Thread(Connect).Start();
}
static void Connect()
{
try
{
Debug.Print("TRY");
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(new IPEndPoint(new IPAddress(new byte[] { 10, 10, 0, 43 }), 80));
Debug.Print("DONE");
}
catch (SocketException e)
{
Debug.Print("THROW");
throw;
}
}
static void BlinkStatusLed()
{
OutputPort onboardLed = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
onboardLed.Write(!onboardLed.Read());
Thread.Sleep(500);
}
}
On 4.1.x: Blocks the blink led thread and never reaches DONE or THROW.
On 4.2b1: The blink led thread keeps working as expected but never reaches DONE or THROW.
4.2b1 Is a very good step but the connection timeout cannot be set.
There are two timeouts available on the socket (SendTimeout and ReceiveTimeout) but not one for connect.
In the normal .NET frameworks in order to allow for Connection timeouts the AsyncCallback and socket.BeginConnect must be used, but in the micro framework the BeginConnect doesn't exist. So that's a no-go.
I tried hacking up a timeout emulation class for a project I am working on but I seem to be having a problem with the Thread.Abort() method.
How it works:
You create a new object ConnectionExtraThreaded, give it the endpoint ip, three callbacks (success, failure, timeout) and a timeout in milliseconds.
The object will start two threads. Connection and Timeout.
When the user specified timeout is reached the Timeout Thread will try to Abort() the Connection Thread.
This is where everything gets messy.
It keeps throwing an exception over and over again. I understand that this is normal .NET activity but can't find a way to properly kill the connection thread.
Any hints/ideas?
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
namespace sample_sockets
{
public delegate void ConnectionExtraThreadedSuccessCallback();
public delegate void ConnectionExtraThreadedFailureCallback();
public delegate void ConnectionExtraThreadedTimeoutCallback();
public class ConnectionExtraThreaded
{
private IPEndPoint endPoint;
private int millisecondsTimeout;
private ConnectionExtraThreadedSuccessCallback successCallback;
private ConnectionExtraThreadedFailureCallback failureCallback;
private ConnectionExtraThreadedTimeoutCallback timeoutCallback;
private Thread connectionThread;
private Thread timeoutThread;
public ConnectionExtraThreaded(IPEndPoint endPoint, ConnectionExtraThreadedSuccessCallback successCallback,
ConnectionExtraThreadedFailureCallback failureCallback, ConnectionExtraThreadedTimeoutCallback timeoutCallback,
int millisecondsTimeout)
{
this.endPoint = endPoint;
this.millisecondsTimeout = millisecondsTimeout;
this.successCallback += successCallback;
this.failureCallback += failureCallback;
this.timeoutCallback += new ConnectionExtraThreadedTimeoutCallback(this.ConnectionThreadKill);
this.timeoutCallback += timeoutCallback;
this.connectionThread = new Thread(this.Connect);
this.timeoutThread = new Thread(this.Timeout);
this.connectionThread.Start();
this.timeoutThread.Start();
}
private void Timeout()
{
Thread.Sleep(this.millisecondsTimeout);
Debug.Print("ConnectionExtraThreaded: Connection timed out after " + this.millisecondsTimeout / 1000 +
" seconds. Executing timeout callback.");
this.timeoutCallback();
}
private void ConnectionThreadKill()
{
Debug.Print("ConnectionExtraThreaded: Killing connection thread.");
this.connectionThread.Abort();
}
private void Connect()
{
try
{
Debug.Print("ConnectionExtraThreaded: Attempting connection.");
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(endPoint);
Debug.Print("ConnectionExtraThreaded: Connection was successful. Executing success callback.");
this.successCallback();
}
catch (System.Threading.ThreadAbortException e)
{
Debug.Print("ConnectionExtraThreaded: Connection aborted.");
}
catch (Exception e)
{
Debug.Print("ConnectionExtraThreaded: Connection died.");
}
}
}
public class Program
{
static void Main()
{
new Thread(BlinkStatusLed).Start();
new Thread(Connect).Start();
}
static void Connect()
{
new ConnectionExtraThreaded(new IPEndPoint(new IPAddress(new byte[] { 10, 10, 0, 43 }), 80),
connectionSuccess, connectionFailure, connectionTimeout, 5000);
}
static void connectionSuccess()
{
Debug.Print("SUCCESS");
}
static void connectionTimeout()
{
Debug.Print("TIMEOUT");
}
static void connectionFailure()
{
Debug.Print("FAILED");
}
static void BlinkStatusLed()
{
OutputPort onboardLed = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
onboardLed.Write(!onboardLed.Read());
Thread.Sleep(500);
}
}
}
}