Something higher up can catch, if need be. this way you can write a function which is supposed to throw exceptions in cases of failure, but not leave resources hanging about. An example would be executing arbitrary SQL; you might want to do;
01 void ExecuteSql(string sql)
02 {
03 connection.Open();
04 try
05 {
06 // execute SQL
07 }
08 finally
09 {
10 connection.Close();
11 }
12 }
And the effect here is that you have a function which still throws if your SQL is bad, but doesn't have the side-effect of leaving you with an open connection dangling about. That feels like a safer function to call.
try/finally isn't something I find myself using very often at all, I think because the IDisposable pattern is actually translated into it - the code above is (nearly?) equivalent to;
connection.Open();
using(connection)
{
// execute SQL
}
so I guess IDisposable is the preferred way in MS' codebase.
(All code is typed late at night into a textbox and totally untested. ;) )
PS: @politician confirms that `using` is translated to try/finally (http://news.ycombinator.com/item?id=3440969) so that's why you don't see it much -- `using` is syntactic sugar for it.