C
C#2mo ago
Faker

✅ using keyword for resource management in C#

Hello guys, I just learnt about the using keyword for resource management in C#. What I understood about it is that whenever we are done with using specific resources, like dealing with database operations, the using keyword automatically dispose/free memory (please add up to the use of this keyword if I'm missing anything or incorrectly saying things). I have one question though. I read that even though if our console application crashes, IF we are not using the using keyword or try-catch-finally block, the resource allocated isn't freed immediately, like it's still allocated to SQL Server for example. I'm a bit lost here, our app is no longer "alive", then how come resources is still available to our SQL server database. Also, when using the using keyword, we don't need to close the database connection like connection.close() anymore? This is already been taken care of under the hood?
28 Replies
Ꜳåąɐȁặⱥᴀᴬ
by "still available" you mean that you still see the open connection (and the an allocated resource/port) in sql server?
Faker
FakerOP2mo ago
Euh I don't know how to check it in the server but I read that the resources are still allocated and not freed
Ꜳåąɐȁặⱥᴀᴬ
read as in "i read the theoretical concept" or read as in "i can look at some place which says that something has not been freed"? physical resources like for example tcp connection will be freed from os (or by the framework if it catches it before exiting), logical resource that require commands to be freed may remain still allocated
Faker
FakerOP2mo ago
Theoretical concept, like they said the session is still valid when it crashes until it timed out
FusedQyou
FusedQyou2mo ago
When a class implements IDisposable, it has an explicit Dispose method to dispose of unmanaged resources. To implement this, you generally do this:
IDisposable? disposableVar;
try
{
diposableVar = Create();

// use the variable...
}
finally
{
disposableVar?.Dispose();
}
IDisposable? disposableVar;
try
{
diposableVar = Create();

// use the variable...
}
finally
{
disposableVar?.Dispose();
}
It ensures it is disposed, even if an exception is thrown It's a lot of code, so any class implementing IDisposable can also use a using keyword:
using (var disposableVar = Create())
{
// use the variable...
}
using (var disposableVar = Create())
{
// use the variable...
}
It does the same thing. Later .NET versions changed this more and made it possible to remove the scope
using var disposableVar = Create();

// use the variable...
using var disposableVar = Create();

// use the variable...
This variable is now disposed when the method scope ends. It basically wraps the whole thing in a try-finally. Depending on the use case you might not want to do this since you might want to use the context of the class outside of the method, so you should be careful with it. There's also IAsyncDisposable. This is an async variant of Dispose called DisposeAsync with the same purpose, but async. You use this with the using keyword, but instead you use await using so that the asychronous method can dispose it asynchronously. Generally methods implement both Dispose methods so you're not tied to making the method sync over async or force blocking
await using var disposableAsyncVar = Create();

// use the variable...


// Or
await using (var disposableAsyncVar = Create())
{
// use the variable...
}
await using var disposableAsyncVar = Create();

// use the variable...


// Or
await using (var disposableAsyncVar = Create())
{
// use the variable...
}
Faker
FakerOP2mo ago
yep I see I will stick with this for now, it's more beginner-friendly good to know the other methods too though this never ends?
FusedQyou
FusedQyou2mo ago
In the end it's all syntactic sugar and it makes no difference
Faker
FakerOP2mo ago
I mean, since there are no scope ? yep true
FusedQyou
FusedQyou2mo ago
It does, 1 sec
Faker
FakerOP2mo ago
Ok
FusedQyou
FusedQyou2mo ago
See it just wraps the whole thing
Faker
FakerOP2mo ago
ah I see
FusedQyou
FusedQyou2mo ago
It's hard to see because it's only one inner method but the whole M method will be wrapped in a try-finally
Faker
FakerOP2mo ago
yeah, the "parent" method is the scope? Like if we would use it in the main method, it would have been the main method the scope ?
FusedQyou
FusedQyou2mo ago
It adds the remainder of the method to the second one IMO it would have been better if it ended the try scope as soon as the last instance of @class2 was used but it probably has a reason
Faker
FakerOP2mo ago
ahh I see Thanks ! /close
FusedQyou
FusedQyou2mo ago
Oh, I believe my thumbs up reopened the thread
Faker
FakerOP2mo ago
np. I will close it 😂 happened to me too yesterday
Faker
FakerOP2mo ago
sorry last question, noticed the finished 2 console log is inside the try block
No description
Faker
FakerOP2mo ago
I thought the scope finished as soon as we no longer use the Class2 variable, like after disposableClass2.DoWork() but this isn't the case?
FusedQyou
FusedQyou2mo ago
Not if you don't explicitly define the scope like with this second one It just wraps the remaining part of the method in the try block
Faker
FakerOP2mo ago
yeah I see, so whatever would come next will be wrapped in the try block ?
FusedQyou
FusedQyou2mo ago
Hence why you might want to use the first one in some cases Yes
Faker
FakerOP2mo ago
yep noted, thanks ! I wrote the first one in my IDE and rider suggest me to use the "using declaration", that's the second method; I should listen to my IDE here?
FusedQyou
FusedQyou2mo ago
Generally the second approach works because scope is not important. However, they have very distinct differences due to the fact the scope might have to be disposed early. I suggest you stick to the first approach and suppress the IDE suggestion.
Faker
FakerOP2mo ago
yep noted 👍 , thanks once more

Did you find this page helpful?