Multithreading: “interrupting” threads waiting

Ok, now that we’ve seen the basic kernel synchronization objects that you can use in .NET programming, I guess that it’s a good time to talk about how we can wake up a waiting thread without signaling the kernel object on which the thread is waiting for.

In .NET, any blocked thread can be awakened by calling the Thread.Interrupt method. For instance, take a look at the following example, where we create a thread and then make it go to sleep:

var anotherThread = new Thread(() => {
                Console.WriteLine("thread started");
                try {
                    Thread.Sleep(5000);
                }
                catch (ThreadInterruptedException ex) {
                    Console.WriteLine(ex.ToString());
                }
            });
anotherThread.Start();
anotherThread.Interrupt();

As you can see, whenever we suspect that someone will wake up the thread by calling the Interrupt method, we must also wrap the call that blocked the thread in a try/catch block (if we intend to do something when the thread awakes up). Even though I’ve decided to go with a sleep example, don’t forget that you can also use this with a thread that is waiting on a kernel object to become signaled or with a thread that is waiting on another thread (ie, has called the Join method).

Now that you know that the method exist, you should probably forget about it. If you’re writing general .NET code, then there really isn’t any way for you to know (for sure) what a thread is doing. And if you’re using 3rd party assemblies,then I’d say that you can’t really know if that assembly is prepared for handling this kind of exceptions…

Two important things you should know:

  • if the thread isn’t blocked,then the exception will only be thrown when it gets blocked (if it never gets blocked, then the exception will never be thrown);
  • thread interruptions aren’t processed if the thread is in a catch or finally block.

Just to test the last point, you can change the code to something like this:

var anotherThread = new Thread(() => {
    Console.WriteLine("thread started");
    try {
        throw new Exception();
    } catch (Exception ex) {
        Console.WriteLine("in catch");
        Thread.Sleep(5000);
        Console.WriteLine("out");
    }
});              
anotherThread.Start();
Thread.Sleep(1000);
anotherThread.Interrupt();
Thread.Sleep(1000);

As you can see, you won’t get any exception thrown when the thread that is being interrupted is waiting inside a catch block. And that’s all for today. Keep tuned for more on this topic.

Advertisements

~ by Luis Abreu on May 20, 2009.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: