BrandGhost

Handle Exceptions Like a BOSS - Try Catch Finally and Disposable in C#

Exception handling is an important part of programming, and in C# in particular. We have try catch in C# to help us with being able to catch exceptions, but we can take it a step further with try catch finally! The finally block is often used for helping run clean up code. It wouldn't be fair to make this video without mentioning another related pattern that we have, and that's the dispose pattern using IDisposable in C#!
View Transcript
if you're getting started off using C and working in net without a doubt you've come across exceptions and you've probably seen try catch blocks that we can go Implement to help handle exceptions but I want to talk about the third part of the TR catch block and that's the finally block hi my name is Nick centino and I'm a principal software engineering manager at Microsoft in this video I want to walk you through the behavior and the reasons why we have a finally block associated with try catch so we'll be looking at try catch finally with a a couple of really basic scenarios but I want to show you when the code and how the code runs when we have a finally block set up after catching those exceptions a quick reminder to subscribe to the channel and to check that pin comment for my courses on dome train with that said let's jump over to visual studio and check out try catch finally all right on my screen I just have a very basic example of what try catch finally looks like and I have a whole bunch of console right lines so we can see when this stuff executes so I'm going to go ahead and run this and I'm going to pull it up beside all of the code so we'll see that of course this code is not currently throwing an exception but if I have both of these things together let's zoom in a little bit here we can see that we get the code running before the TR catch finally and then we have these two like line four and six that output back to back because there's no other code running there we don't get line 10 printed because there is no exception and then the code inside of the finally block on line 14 is the last part to print to the console here so very simple pretty straightforward and then we know if we go to throw an exception anywhere inside of this Tri portion of the the tri catch block right so anything between line four and seven we know that we're going to hit this catch block as long as the exceptions met and this filter that we have in the catch block is for any exception right so that or this will catch any exception that is catchable inside of net if you did not have the correct exception filter set up so you were trying to catch a very specific exception then of course we wouldn't see it happen but if we threw an exception anywhere in here we know the catch block will get hit and the way that the finally block works is that it will run after the exceptions caught or in the happy path as well so we already saw the happy path run we saw that the final output that we got was line 14 and that means if we wanted to have something like cleanup code we can use a f finally block to say hey look like once we run the code up here even if it's successful we want to do it and run this code down here or if it throws an exception and we catch it we still want to run the finally block so to kind of prove that happening I'm going to throw an exception between these two lines right so when I go to throw this exception here you can see line six is actually grayed out inside of Visual Studio it knows that it's unreachable code but what we should see now is line one line four get printed out then we'll get the catch block and then we will still get this finally block printed right so the new line that we see coming up here is this is in the catch block so again this isn't super exciting but this is the basic behavior of the finally block it runs code after your happy path succeeds so once all of this code runs or if you throw an exception anywhere up here and it's met by this catch block we will go run the finally block now there's a bit of a Nuance to what I'm saying as well because I said if it's caught by this catch block and we're going to see in a little bit just what that means because sometimes the finally block will run and other times it won't and you might be asking yourself well how the heck can the finally block not run right isn't that the whole point of having the finally block well I want to show you a simple example coming up in just a moment where that doesn't work okay so the next example that we're going to look at is a really common pattern that happens and it's often one of the reasons we have this concept of a finally block it's because we want to have some type of cleanup work that happens after we go run some code now I'm going to show you using what's called an i disposable object so down here you can see that I have a new class called my resource it implements this interface which has one method on it called dispose by the way this is built in if you haven't used it before and I'm just going to write to the console that we've called this method now we're going to look at some more advanced things that we can do with this class after but this is just to illustrate the patterns so you'll notice a very similar setup to what I just had right I'm going to make the resource outside of the tri catch block and the reason for doing that is that I want to on line 30 try to do the cleanup code now if I didn't have it declared outside of that right if I put it inside here we can't actually access resource because the scope of it is limited to line 19 through 23 it's just not in scope for us to access inside of the final block so it makes it a little bit awkward in my opinion to have to do it outside of the TR catch finally just to access it here but this is how you would go about this now the way that this works again we're going to talk about the happy path first is that we can have a right line before the TR catch finally I'm not going to throw an exception and then I wanted to show you that we can go dispose of that after so we should see this line and then the dispose line get printed because that's being called inside of the finally block and again not super exciting but we see these two lines printed one after the other so the finally block is doing what we would have expected in this case very much like the first example right so I'm going to go ahead and show you that if we go throw an exception now that we still get that behavior that we want so it will be very much like the very first example that we saw inside of this but this is before the TR catch finally this is in the catch block and then the dispose method right this line here is called from line 30 so this is really how you can set up cleaning things up I did say that I wanted to show you an example of where this finally block will not run though and here's a bit of an interesting one so if we throw an exception so this is a base exception type if I put invalid operation exception right here so now we're trying to catch a specific example you would think that what should happen with a TR catch finally is that we throw the exception here it does not get caught but we still have to go run this finally block right well let's go see in this case you can see that it hit this line throwing an exception right there's nothing to catch the specific exception when I press F5 to continue the program you can see that we never got to see the dispose method getting called right it says this is before the tri catch then we see the unhandled exception but there's no code that actually runs the dispose method so this is one particular example where that's not happening right the dispose method or anything inside of the finally block is not getting called the reason that that's happening is because the program itself is terminating it's kind of weird because I'm going to show you in just a moment how you could air quotes fix this that make the finally block run but it changes the behavior of the program so if I put a try here around the whole thing so it's a big TR catch around the other tr catch and then I use this to catch all exceptions if I go run this now what happens is that this prevents the program from crashing this is a catch all it's the same as doing this right if that's more comfortable for you to read it means that this won't catch the exception this one will but the finally block will actually go run in this case which I find pretty fascinating so if we look here we do see that we call dispose right that actually worked um and maybe we can put in some other console right lines to see the order of things because the reason again that I find this interesting is that the finally block should go run right after the catch but because the program was terminating before it never did now that we can save it from terminating it will go run the finally block so this is not being caught there I'm going to say this is in the catch block two so we can see the outer catch block maybe I'll call it outer catch block just to make it a little bit more obvious so this works as we expect right this is before the TR catch this is disposing of the resource in the finally block and then of course this catch is handled outside so I think it's pretty cool that or maybe interesting and not cool that finally that finally block that we saw it will run only if the program is not about to terminate for the most part you might be like well yeah Nick that's totally fine the program is already you know about to blow up I don't care if I go you know dispose of something but it depends what you're doing inside of your dispose method where you might say I really need to guarantee even if my program is terminating that I try to clean up as best as possible so a bit of an edge case I would say but I wanted to illustrate to you that there is a slight difference in the behavior of the finally block if your program's terminating or not it might not ever impact you just wanted to call it out okay so we have the try catch finally block and we were looking it finally being used to help clean things up now it wouldn't be fair if I left out the details of what disposable is and how we can work around having a finally block so instead of having the TR catch finally block setup just so that we can do some typ type of cleanup like calling dispose on our object instead we can use What's called the using pattern and we have a using block as you can see here on line 35 and this is a keyword that only works with I disposable implementations so if I take this off even though it still has a dispose method you can see line 35 is now complaining and it says that the type used in the using statement was being implicitly convertible to system I disposable so it needs to have this interface that's built in to be used like this the way that this works is it's very much like having a finally block to go run some things to clean up so I'm going to go press play right there's no exception being thrown in this case so we can see that this is before the using block then we get the line right inside of the using block right here then disposing the resource you might say well where is that happening well as soon as we leave the using block so once we leave line 41 and exit the using block that's going to call dispose which is going to print this line 55 here and then after we see the line printed for this is after the using Block it's a really nice way to clean this kind of code up but how does it work when we're throwing exceptions right that's what we were trying to deal with before so let's go throw an exception and see what happens well you might see something kind of funny here this might look familiar right we throw an exception nothing's catching it if I go check the output did we get to see the using statement terminate and get the dispose method called and the answer is no so we got these two lines printed but just like earlier when there was nothing to catch the exception the program was ending it did in fact not get a chance to run the dispose method if the exception is not going to terminate the whole program you should get the behavior you expect so let me go ahead I'm going to put a try holy that is way too much in front of my screen right so I'm going to do this I'm going to catch everything once again so when we go to do this I'm going to put um that it's in the outer catch block oh there's only one catch block sorry so we have the using statement and then this catch block outside I want to show you that the dispose method will get called still before this outer catch block and it's really because the program's not terminating right so we can see now that the using statement does what we expect when we leave and we get to line 43 now once we go over that it will call the dispose method and the program is not terminating obviously because there's a catch block on the outside of the whole thing so if your program's not terminating your using statement should do exactly what you expect and dispose of the object once it's leaving and now I want to show you the very simple version that we have of this available to us inet so we went from having try catch finally to having a using block to just having this simple expression with using out the front this is not to be confused with the top level import statements where you're saying like using some namespace this is in fact just like the using block but it's implicit you'll notice that I don't have curly braces it's not the same as doing this which is probably a little bit confusing because this will only treat one line below it when there's no curly braces so it is different when you do this and the way that this works as a using statement is that once the variable in this case resource 3 once that goes out of scope that's when the dispose method is going to be called so it's implicit because the explicit version must have waited until we hit the end curly brace this just says once the variable goes outside of scope then we'll call dispose again it only works on I disposable just like the last example but I don't need to go run this and show you the behavior of it again because it is identical to how the using block worked we just don't need to have the curly braces and the parentheses around this there are situations where you might say I just need to use this variable inside of the scope that I'm working in so say it's in a given method and there's other situ where you want to have a lot more granular control and you do want to have a using block and before your method ends or something you want to call dispose before you keep continuing so different use cases but this is an implicit using and I just wanted to mention tying it all back together that try catch finally that finally block is often used to try and clean this kind of stuff up now all of this is because we have to deal with exceptions inside of c and unfortunately there's going to be code that we're using and leveraging that's outside of our control and someone wrote that code that's going to be throwing exceptions and of course there always will be exceptional cases but if you're curious about dealing with code that doesn't have exceptional cases and you want to move away from using exceptions to try and indicate error State you can go ahead and watch this video next for some ideas thanks and I'll see you next time

Frequently Asked Questions

What is the purpose of the finally block in a try-catch-finally structure?

The finally block is used to execute code after the try and catch blocks, regardless of whether an exception was thrown or caught. It's typically used for cleanup tasks, ensuring that certain code runs even if an error occurs.

Why might the finally block not execute in some cases?

The finally block may not execute if the program is terminating due to an unhandled exception. If an exception occurs that isn't caught by any catch block, the program may exit before reaching the finally block.

What is the difference between using a try-catch-finally block and a using statement?

The using statement is a more concise way to ensure that resources are disposed of properly. It automatically calls the Dispose method when the code execution leaves the using block, similar to what a finally block does, but it is specifically designed for objects that implement the IDisposable interface.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload