LA.NET [EN]

May 20

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.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>