Check out a free preview of the full C# and .NET Basics course
The "Dispose Pattern" Lesson is part of the full, C# and .NET Basics course featured in this preview video. Here's what you'd learn in this lesson:
Spencer explains the concept of the Dispose pattern in C#. He discusses how resources, such as database connections, need to be explicitly disposed of to prevent them from being kept open indefinitely. He introduces the IDisposable interface and demonstrates how to implement it to release unmanaged resources. Spencer also explains the `using` keyword, which provides a convenient way to automatically dispose of resources at the end of a code block.
Transcript from the "Dispose Pattern" Lesson
[00:00:00]
>> Spencer Schneidenbach: Okay, moving on to dispose. So the dispose pattern is something that you need to know as you're dealing with resources that need to be cleaned up. So as I mentioned earlier, when a value type variable goes out of scope, goes outside of its curly braces, it's removed immediately.
[00:00:19]
The reference types that are declared are eventually removed by the garbage collector. But there are some things that some reference types that represent other things where disposing of them and destroying them have to be done explicitly. So think about a connection to like a database. A database connection will be kept alive for as long as the the construct itself doesn't know when it's appropriate to close that connection unless the developer specifically instructs it to do so.
[00:00:49]
And if it doesn't instruct it to do so, it will keep that connection open, even if the even if the variable the SQL connection that exists is supposed to be taken by the garbage collector. It may be a while before the garbage collector gets to it and actually disposes of it.
[00:01:07]
So this is where the dispose pattern comes in. So this gives us more control as developers, over when we want to remove resources. So this is important for things like you know, you can only have so many connections to a database within an application. Or you don't wanna have a bunch of files open and reading from them all at one time and then just keep those files open so that nobody else can access them, no other programs can access them.
[00:01:33]
>> Spencer Schneidenbach: So this kinda goes into this idea of unmanaged resources, right? The.NET Core library manages, a lot of this stuff for you. But there's certain things that it simply does not. So database connections are among the most common of those. So let's talk about this thing, the IDisposable interface.
[00:01:50]
So IDisposable is designed for types that need to release unmanaged resources where the developer needs to be the one to explicitly release those resources. So let's take, for instance, something that owns a SQL connection. As I mentioned, if this thing isn't properly disposed of by the developer, it's just gonna hang out in memory and keep that connection alive, such that it might prevent somebody else.
[00:02:13]
If you get 100 connections, the 101st connection may fail, right? So what you wanna do is Is implement this interface. iDisposable is the interface that kind of makes dispose work, okay? And what that is, is it's simply a method called public void dispose, and what you do is simply go through and if you have a, you might.
[00:02:40]
It's common to have kind of a marker to say, has this object been disposed or not? And if it has, then if it has, then just exit this method. We don't wanna do anything, but if it hasn't go through, if it hasn't been disposed yet, dispose of that connection, free up that connection so that somebody else can use it so that we're not keeping an open connection that we're not using.
[00:03:01]
And then set the disposed variable to true, so that way down the line, if multiple calls to dispose happen, you don't try to redispose something that's already been disposed like connection. Which would probably cause an exception. So Idisposable is an interface provided by the runtime, it's provided by .net.
[00:03:22]
But it's so integrated into the runtime there's a language keyword that is used for managing those resources, disposed, even in the case of an exception, and it's called the using keyword. So anything that implements IDisposable, as long as it implements I disposable, and technically speaking, it really just needs to have a public void Dispose method on it.
[00:03:56]
You can wrap it in a using statement, and then you can use your resource. And at the end of this code block, at the end of this using block, that resource will be released, okay? Again, in the context of a web application, you only wanna keep a connection open for as long as you need to connect to that database, do the operation.
[00:04:13]
Cause the database can't accept infinite number of connection, nothing can. That's what the using keyword is for. Recently, in the last few versions of they've actually made it so that you can put your using next to your variable declaration and skip using inside of this block altogether. I tend to think that I don't like this because I really wanna dispose of my resource as quickly as I possibly can not necessarily when this variable drops out of scope, cuz oftentimes I will want to do something in that variable scope.
[00:04:46]
I wanna keep doing a few more things, but I want this to be completed and disposed of. So I like to keep my usings inside of this block, because it tells me exactly, it's very explicit about when this resource will go away. It's really important to note, if an exception happens inside of a using block, the object will still be disposed.
[00:05:09]
It essentially is syntactic sugar, or just a convenience way of doing a giant try catch finally, and inside that finally, it basically that's what a using a statement converts to. And inside that finally, it will always call dispose to make sure that that resource is freed up, even if there's an error, so really important part of of understanding that.
[00:05:30]
Cuz if you have an object and you don't have a using statement, you have three statements below that, one of those throws an exception, and your disposes at the bottom of the method at Dispose isn't gonna get called because an exception got thrown. So it's a really important, really critical part of the whole system.
[00:05:48]
Async dispose is a relatively recent addition, essentially, you don't have to you can. There's a an interface called IAsyncDisposable, which essentially is a dispose suppose method that returns a task so that you can await on it. It's not super critically important to necessarily use it. If it's available, you should use it.
[00:06:10]
Because if you can be async all the way down, then you should. But as long as you're using a using statement to wrap it, I think that's tends to be more important, but use a weight, using as much as you can in the places that you need to do.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops