views:

88

answers:

1

Why is my Thread.Interrupt not working?

The code doing the interrupt:

public void Stop()
{
    const string LOG_SOURCE = "ProcessingDriver";

    if (_Enabled)
    {
        try
        {
            RequestProcessor.Disable();
            if (ProcessingThread != null)
            {
                ProcessingThread.Interrupt();
                ProcessingThread.Join();
            }
        }
        catch (Exception ex)
        {
            WriteLog(LOG_SOURCE, ex);
        }
    }
}

The code that I expect to stop:

private void ProcessRequests()
{
    const string LOG_SOURCE = "ProcessRequests";
    try
    {
        ProcessingThread = Thread.CurrentThread;
        while (!_Disposed)
        {
            _ProcessingWaitHandle.WaitOne();
            int count = GetRequestCount();
            while (count > 0)
            {
                try
                {
                    ExportRequest er = GetRequest();
                    ProcessRequest(er);
                }
                catch (ThreadInterruptedException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    WriteLog(LOG_SOURCE,
                         ex);
                    WriteLog(LOG_SOURCE,
                        "Request Failed.");
                }
                //Suspend to catch interupt
               Thread.Sleep(1);
                count = GetRequestCount();
            }
        }
    }
    catch (ThreadInterruptedException)
    {
        WriteLog(LOG_SOURCE,
            "Interupted. Exiting.", LogType.Info);
    }
    catch (Exception critEx)
    {
        //Should never get here
        WriteLog(LOG_SOURCE, critEx);
        WriteLog(LOG_SOURCE,
            "Serious unhandled error.  Please restart.", LogType.Critical);
    }
}

I have stepped through the code. I can see Interrupt being called (Sleep or wait are not the active commands at the time), and I can see sleep being called, but no Interrupt error is ever thrown (neither on the sleep, or on the WaitOne, even when the thread blocks on WaitOne).

What am I doing wrong?

Note: .Net 2.0

+3  A: 

Hmmm... it does look like it should work, but I would advise you not to use Interrupt in the first place. Use events and/or Monitor.Wait/Pulse to tell the thread that you want to stop. That's a generally simpler approach, and one that gives the worker thread more control over stopping in an orderly manner.

Jon Skeet
I like the Interrupt method because it would automatically kick out of my _ProcessingWaitHandle.WaitOne();
C. Ross
Jon is right. Here is why: http://www.bluebytesoftware.com/blog/PermaLink,guid,c3e634ac-4aa1-44eb-a744-02d6ed4de514.aspx
Craig Stuntz
C. Ross: The point of a wait handle is that you can Set it without just interrupting the thread...
Jon Skeet
@Jon: But since I'm already blocking on one wait handle, I'd have to come out of that one to check my new "TimeToQuit" wait handle. Esentially I'd have to poll between my two handles.
C. Ross
@C. Ross: What about WaitHandle.WaitAny() ?
Chris W. Rea
@cwrea: Good idea. I'll still have to check a flag afterwards to see if I should exit, but that would work.
C. Ross