The using block

Any program is bound to have errors. There could be several unforeseen circumstances where our written logic will throw exceptions. 

If we are using unmanaged resources, then unhandled exceptions can be very harmful. They can lead to issues related to dangling memory, unclosed connections to file objects, and more. 

For example, consider the preceding example, where we have written a Dispose method to free up the memory. Let's say we have a scenario in which the application throws an exception before the Dispose method is called. In this case, the application will never have a chance to reclaim the memory occupied by the unmanaged resources. 

To avoid such scenarios, C# lets us use the using block in our code. When we use the using block, no matter what happens inside the using block, the Dispose method is always called. Let's understand this with the following code implementation:

using (DisposeImplementation d = new DisposeImplementation())
{

}
Console.ReadLine();
GC.Collect();
Console.ReadLine();

Note that in the preceding code block, we are using the same DisposeImplementation class but are using it inside the using block. We are not explicitly nullifying the d object, to indicate to the garbage collector that it's no longer needed. Additionally, we are not explicitly calling the Dispose method to free up the unmanaged resources. Yet, when we run the program, we get the following output:

The using block handles it automatically. The using block ensures that as soon as the control is out of the using block, it will call the Dispose method for the object. 

Now, let's consider a scenario in which we get an error in the using block. For the sake of explanation, we will introduce an error manually by throwing an exception.

The following is the code snippet for this:

using (DisposeImplementation d = new DisposeImplementation())
{
throw new Exception("in here");
}

If we execute the code, we get the following result:

Now, in the code, we have thrown an exception that is not being handled. However, even then, the Dispose method of the DisposeImplementation object is called before the application errors out due to the exception. If we don't use the using block, this will not happen. To illustrate this, remove the using block and throw the same exception in the application. The following is the code implementation for this:

DisposeImplementation d = new DisposeImplementation();
throw new Exception("in here");

In the preceding block, we have removed the using statement and are throwing an unhandled exception after the object is created. If we execute the code, we get the following output:

As you can see in the preceding screenshot, during the program execution the Dispose method is never called for the DisposeImplementation object. This illustrates that, as a best practice, we must always use a using block for classes implementing the IDisposable interface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.35.122