Improper use of exceptions

The .NET Framework’s ReaderWriterLock class API is broken. How? It uses exceptions where it should use return values. Consider the AcquireReaderLock method, which you call with a timeout value. If the timeout expires before the lock is acquired, the method throws an exception. This is nuts. The use of exceptions here makes for some very ugly code. Consider, for example, code that waits five seconds for a reader lock:

try
{
    MyLock.AcquireReaderLock(5000);
    // do processing here
}
catch (ApplicationException)
{
    // unable to acquire lock.
}

A temporarily unavailable resource is not an exceptional condition. It’s quite common for a resource to be locked a little longer than normal. Whoever designed the Monitor class understood that. Monitor has a TryEnter method that accepts a timeout value and returns a Boolean value: True means that it acquired the lock, and False means that the timeout expired and it didn’t acquire the lock. If whoever designed the ReaderWriterLock interface had studied Monitor, perhaps we would have a TryAcquireReaderLock method that would make for much more reasonable code:

if (!MyLock.TryAcquireReaderLock(5000))
{
    // do processing here
}
else
{
    // unable to acquire lock.
}

Exceptions are meant for exceptional conditions. Using an exception to indicate a normal failure is totally inappropriate. I can think of no rational reason why AcquireReaderLock or AcquireWriterLock should ever throw an exception.

[Note, posted many years later. I overstated my case here. Of course AcquireReaderLock and AcquireWriterLock should throw exceptions if they fail. I think my issue is more with the design of the API: those two methods shouldn’t exist. They should be replaced with TryAcquireReaderLock and TryAcquireWriterLock, and the old methods deprecated.]