开发者

Actual use of finally block

I asked to my frien开发者_JAVA技巧d about this question, he said that it is used for destroying the object created during the exception handling. But in c# GC is there for destroying such kinds of unused objects, then what is the actual use of finally block. Tell me with a scenario related to that.


It is a block that is guaranteed to run whether or not an exception occurs.

So typically, you would use it if there is some sort of resource that you want to ensure is properly released. Nothing to do with objects created during the exception handling. But say you had a connection of some kind to a database, or a file handle.

If it's a managed object that implements IDisposable, a better approach is normally the using keyword.


The GC will clear managed resources (objects your application has created in memory) when they are no longer referenced. This doesn't include things like file handles, network resources, database connections etc... You must clear them up yourself in the finally block or risk them not clearing (although most will clear eventually).

OR, more commonly:

Many classes which which unmanaged resources to be disposed of implement the IDisposable interface. This means you can wrap the code in a using block and be sure that the unmanaged resources will be cleared (it calls the object's Dispose() method when it goes out of scope).

A good example of using the finally block is when you use an Office interop library. Say you open Microsoft Word, run some code, code fails...Word will always need closing regardless of whether an error occurred or not. Therefore I would put the closing code in the finally block.


The GC will eventually destroy the object, that's true. But the finally block is useful when you have non-memory resources that would be best released ASAP. For example, if you have a database connection, you don't want the connection to remain open for a (possibly indertminately) long time until the finalizer runs, so you put it inside a using block (which is just syntatic sugar for a try ... finally block):

using(var conn = new SqlConnection(...))
{
    // use the connection
}

This is syntactic sugar for (basically):

var conn = new SqlConnection(...);
try
{
    // use the connection
}
finally
{
    conn.Dispose();
}

Now, if you didn't have the finally/using, then the connection would eventually be disposed when the object's finalizer runs, but because you don't know what that will happen, it's better to wrap usage of the object in the using block to ensuer that the connection is closed as soon as it is no longer needed.


finally is used to ensure the execution of certain operations whether or not an exception occurs.

One of the use - albeit not much "elegant" - is a call to close() on a previously opened db connection. More in general is used for all the things that the GC does not clear up (such as db or network connections).

http://msdn.microsoft.com/en-en/library/zwc8s4fz(VS.80).aspx


finally block is used, when you want a piece of code run irrespective of the exception has occured or not. For example to close a database connection.


finally block is not only for memory releasing! Think about this case: within a 'try' block you - 1. Open a connection to a DB 2. Execute a query step 2 failed with an exception. However, in any case, you should close the connection to the DB - the right place to do it is within a finally block.

This is only an example. There are many many different cases that may need the finally block.


The garbage collector will collect managed resources in due time. For those that also hold on to unmanaged resources like network resources, database connections or file handles etc, they normally support the IDisposable interface, and if done correctly will still free up the resources via a finaliser; however by Dispose()ing in a finally block allows you to control when these resources are released.

If you only have a single IDisposable object, then a using block may be more appropriate, although the jury is still out if you either (a) need to handle exceptions thrown within the block, or (b) have a few IDisposable objects all being used together (say, SqlConnection, SqlCommand...)


In addition to the other scenarios mentioned, another common one occurs with locks. A synclock statement calls Monitor.Enter and execute a block of code; it then uses a finally block to call Monitor.Exit. If code were to leave the block without calling Monitor.Exit, then any other attempt to use the resource guarded by the lock would be blocked forever.

Incidentally, even if something bad happens inside the synclock such that the resource guarded by the lock should be considered corrupt and not used, leaving the lock held is not a good way to handle that situation. A much better approach is to have code inside the synclock explicitly invalidate the object in such a fashion that any other code which is waiting on the lock will be granted access and then end up throwing an exception when it tries to use the invalidated object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜