3

I have the following code, I want to abort a thread if it is unfinished in 2 secs. You can see from the first code that i create a new myThread evertyime in the while loop and do not abort it. Well, I dont want to it to be like this, but if i take the myThread outside the loop and use the abort() function as the second code does. there will be error in aborting.

while (true)
        {

            try
            {
                m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//reset up socket
                myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));
                myThread.Start();
                if (!myThread.Join(2000))
                {
                    throw new SocketException(SocketError.AccessDenied);
                }

            }
            catch (Exception ex)
            {
                m_socket.Close();
            }
        }
    }
     private static void socket_connect()
    {
        m_socket.Connect(remoteEndPoint);//Connect to remote device  
    }

I was trying the following code at first, however it give threadabortexceptions.

 myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));   
  while (true)
        { try
            {
                m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,     ProtocolType.Tcp);//reset up socket

                myThread.Start();
                if (!myThread.Join(2000))
                {

                    myThread.Abort();
                    throw new SocketException(SocketError.AccessDenied);
                }
            }
            catch (Exception ex)
            {
                m_socket.Close();
            }
        }
    }
    private static void socket_connect()
    {
        m_socket.Connect(remoteEndPoint);//Connect to remote device  
    }

I know abort() is not a good idea so I turn to let the threads stay and let C#(.Net? I dont know who actually does that) dealing with the garbage collection. And can anyone tell if it is a good idea since this program will be run on a board which does not have lots of memory for holding bunches of threads. And can someone tell me how exactly the garbage collection is done in C#? for example the threads.
Another thing need to be mention is that i dont have the Task class, or the socket.beginconnect() method, I guess its because i'm building a program that is going to run on a small board, not a pc. The board is a netduido plus and I'm building my project on a netduino plus platform.

henryyao
  • 1,758
  • 6
  • 23
  • 37
  • 7
    "I was trying ... myThread,Abort(); ... however it give threadabortexceptions". Unless I'm mistaken that's what Thread.Abort() does - throws a ThreadAbort exception - that's the point. – 500 - Internal Server Error Jan 30 '13 at 23:38
  • 3
    Why kick off a separate thread just to immediately Join and block the original thread? – mbeckish Jan 30 '13 at 23:43
  • 2
    How do you know that the problem is access denied? And note how you are discarding all information in the Exception object when you catch the exception. – John Saunders Jan 31 '13 at 00:18
  • Please read [Remarks](http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx). – ta.speot.is Jan 31 '13 at 02:50
  • 1
    Also, just invoke Connect asynchronously and abort it after 2 seconds, like so: http://stackoverflow.com/a/4708790/242520 – ta.speot.is Jan 31 '13 at 02:53
  • @mbeckish I dont get what u mean, can you explain it more? – henryyao Jan 31 '13 at 19:42
  • @JohnSaunders well, u got a point. but i dont think that's the main issue here. – henryyao Jan 31 '13 at 19:44
  • @mbeckish The idea is so that it can be aborted; if you blocked the current thread you'd need the method you're calling to cooperate to kill it. Now, connecting to a socket should have built in mechanisms (i.e. a timeout parameter) so that you don't need to do that. If it was just some arbitrary function that wouldn't be an option. – Servy Jan 31 '13 at 19:52
  • @Servy - My question isn't why connect in a separate thread, but rather why Join immediately after starting a new thread? – mbeckish Jan 31 '13 at 20:00
  • @mbeckish Because only one connection should be open at a time. Without that it would create thousands of connections all at once and start waiting on all of them. – Servy Jan 31 '13 at 20:01
  • @Servy - if you want to block until the connection goes through, then why kick off the connection in a separate thread? – mbeckish Jan 31 '13 at 20:02
  • @mbeckish As I said before, it's a hack designed to add a timeout that stops trying to connect in the event that there is no connection after two seconds. On the full framework version that's quite easy, and doesn't require any use of `Abort`, but I see no mechanism for providing a timeout or cancelling a connection on the micro framework version. – Servy Jan 31 '13 at 20:04

2 Answers2

1

I have the following code, I want to abort a thread if it is unfinished in 2 secs.

Reading into the code, it looks like you actually want to attempt to connect a socket to a resource within two seconds. If more than two seconds elapses, you want to move on.

I'm mostly reproducing the code in this answer, I believe this is approximately what you should be doing to achieve your goal, rather than spinning up a thread and aborting it:

Socket socket = new Socket(AddressFamily.InterNetwork,
                           SocketType.Stream,
                           ProtocolType.Tcp);

// Connect using a timeout (2 seconds)

IAsyncResult result = socket.BeginConnect( sIP, iPort, null, null );

bool success = result.AsyncWaitHandle.WaitOne( 2000, true );

if ( !success )
{
            // NOTE, MUST CLOSE THE SOCKET

            socket.Close();
            throw new ApplicationException("Failed to connect server.");
}

// Success
//... 
Community
  • 1
  • 1
ta.speot.is
  • 26,914
  • 8
  • 68
  • 96
  • the thing is i dont have the socket.BeginConnect() method. I do have the AsyncWaitHandle.WaitOne either. I did added the reference mscorlib.dll and the namespace System. – henryyao Jan 31 '13 at 19:40
  • @henryyao - The Micro Framework version of Socket doesn't have BeginConnect - see http://msdn.microsoft.com/en-us/library/cc506514.aspx – mbeckish Jan 31 '13 at 20:10
  • @henryyao Maybe you will have to around the Micro Framework and use something like http://mip.codeplex.com/ – ta.speot.is Jan 31 '13 at 20:28
-1

[edit: massive copypasta fail when untabbing/spacing]

Oh, please use the Task library, it's way easier to deal with these situations:

(LINQPad-friendly blob)

void Main()
{
    var canceller = new CancellationTokenSource();
    var task = Task.Factory.StartNew(() => DoStuff(canceller.Token), canceller.Token);        
    if(!task.Wait(2000, canceller.Token))
    {
        canceller.Cancel();
        task.Wait(2);
    }
    sw.Elapsed.Dump();
}
private Stopwatch sw;
private void DoStuff(CancellationToken token)
{
    try
    {
        sw = Stopwatch.StartNew();
        while(!token.IsCancellationRequested)
        {       
        }
    }
    // no catch - rethrown exceptions must be checked on Task
    finally
    {
        sw.Stop();
    }
}

Alternatively, you can use some "exit flag" condition - a bool that both your thread-starter and your thread-runner can see/alter, and use that in your while condition.

JerKimball
  • 16,584
  • 3
  • 43
  • 55
  • Does this work? I thought the tasks had to co-operate with cancellation? I.e. check the token themselves. – ta.speot.is Jan 31 '13 at 02:51
  • @ta.speot.is Oh wow - talk about a copy/paste mistake: I somehow chopped a bunch of stuff out of that... – JerKimball Jan 31 '13 at 03:13
  • Did you have to ignore exceptions? – John Saunders Jan 31 '13 at 03:20
  • @JohnSaunders I *promise* I don't write that in actual production code...but in this case, I blame snippet completion. – JerKimball Jan 31 '13 at 03:21
  • I think this is a useful example but when someone says (paraphrasing here) "I want this thread to run for up to two seconds and then cancel it" I (personally) infer that they want the code they're writing to return in no more than two seconds, success or fail. This code could take up to 4 seconds to return. – ta.speot.is Jan 31 '13 at 03:51
  • I dont have the task class. I'm building a program that's going to run on a certain board, not a pc. So there are lots of class that are not supported , I guess. – henryyao Jan 31 '13 at 19:42
  • @ta.speot.is dropped the secondary wait time...2002 ms is close enough, eh? – JerKimball Jan 31 '13 at 20:05