0

I have a log-on process from an API I don't own that occasionally hangs. If it takes longer than, say, 30 seconds, I would like to kill it and retry (as it should take only about 2-3).

I'm a little confused about how aborting threads works, and whether or not I need to join after abortion. Here's my questions followed by an example of what I'm trying to do:

Questions:

  1. Abort throws a thread abortion exception in the thread its called on. Does that propagate? Do I need to explicitly handle in the calling thread it or does the thread just die?

  2. Do I need to join an aborted thread so it doesn't zombify, or am I just confused from the *NIX world of programming?

    public static Session GetSession()
    {
        Session session = new Session("user", "pass");
    
        try
        {
            //Create a thread to get the session so we can kill it if it hangs.
            Thread thread = new Thread(() => session.Logon());
    
            //Create a thread to kill the session thread if it hangs.
            Thread watcher = new Thread(() => HangKill(thread));
    
            //Start both threads.
            thread.Start();
            watcher.Start();
    
            //Wait for session thread to finish - abort kill thread if it does.
            thread.Join();
            watcher.Abort();
            watcher.Join();
        }
        catch (Exception ex)
        {            
            status = ex.ToString();
        }
    
        return session;
    }
    
    
    public static void HangKill(Thread t)
    {
        Thread.Sleep(30);
    
        if (t.IsAlive == true)
        {
            t.Abort();
        }
    }
    
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
John Humphreys
  • 37,047
  • 37
  • 155
  • 255

1 Answers1

1

Aborting threads in your own process is dangerous. (As well as in other processes, though.) The thread may own some locks, may be in the process of updating critical structures etc etc. So this is not the way to go.

I would suggest including the service in question into another process, so you can kill that process if something is going wrong. Use IPC (shared memory? WCF?) for communication with that process.

Vlad
  • 35,022
  • 6
  • 77
  • 199
  • Thank you. This seems very heavy-weight for just wanting to timeout a log-on that hangs though. Isn't there just a way to kill a thread from it's parent (creator) thread? Or do I have to go down the route of the C# version of thread timed waiting, signaling, and condition variables? – John Humphreys Jul 19 '12 at 15:44
  • @w00te: nope, actually no valid way. Sorry for that. The thread can safely terminate itself by jumping to the threads function end, but that's maximum you can do. And this wouldn't help if the threads hangs in the code you don't own. – Vlad Jul 19 '12 at 15:45
  • Haha, okay. I guess I'm screwed. Can I ask what you would do in the same situation (not necessarily what you think is best practice?) – John Humphreys Jul 19 '12 at 15:45
  • @w00te: Well, if the code you need to run is unsafe *crashing, hanging, whatever), I would build a wall around it with locks and armed guards around -- that is, run it in another process. A somewhat more lightweight way could be playing with AppDomains (you can unload one), but perhaps it's too advanced to waste the time on it. – Vlad Jul 19 '12 at 15:49
  • @w00te: anyway, keeping crashing/hanging code running as far as possible from your code must be a good idea in any environment, be that native or managed. – Vlad Jul 19 '12 at 15:50
  • Raise another process and IPC for a logon exercise? You would do that? Really? – Martin James Jul 19 '12 at 17:50
  • @Martin: Execute buggy hanging code in my process -- I wouldn't do this, really. Have you got a better option? – Vlad Jul 19 '12 at 17:51