IDisposable, using and GarbageColleciton [duplicate] - c#

This question already has answers here:
what is relation between GC, Finalize() and Dispose?
(3 answers)
Does C# app exit automatically dispose managed resources?
(4 answers)
What are the uses of "using" in C#?
(29 answers)
Closed 2 years ago.
I got stuck in the weeds of how IDisposable and the GarbageCollector work.
Suppose you have an IDisposable object, which doesn't actually have an resources that it's holding onto (but the Dispose() method is going to do something when called). And suppose you declare it in the head of a using block, but don't actually interact with the object over the course of the block.
What guarantees do I have about how GarbageCollection will operate?
i.e.
using(new MyConceptuallyDisposableObject())
{
DoSomeWork();
await DoSomeAsyncWork();
}//PointX
Note that:
MyConceptuallyDisposableObject doesn't declare a finaliser / destructor.
(Assume that developers will never forget to using`.Dispose()` my object)
MyConceptuallyDisposableObject doesn't call GC.SuppressFinalise(this) anywhere.
Am I guaranteed that the object that I constructed will:
Will not have .Dispose() called on it before PointX?
Will have .Dispose() called on it at exactly PointX?
Will not get GarbageCollected/Finalised at any point before PointX?
Will not get GarbageCollected/Finalised before it has had .Dispose() called on it?
Suppose I then change my code to make MyConceptuallyDisposableObject call GC.SuppressFinalise(this) in its constructor. (Bearing in mind that there isn't any Destructor or Finaliser)
Does that change any of the answers to the specific questions above?
Does anything change in general, then?
Does it mean that the GC never cleans up my object at all and I'll end up with a memory leak?
*Context:*
Posted for those who are inevitably curious, but PLEASE don't answer based suggesting other ways to achieve this or that I shouldn't do this. Right now, I'm much more invested in understanding the guts of the above concepts in their abstract sense, not discussing whether my initial attempt was sensible.
I want to write a DisposableAction() class, which accepts 2 Actions. One to perform when you construct it, and one to perform when you Dispose() it.
I thought I knew all the answers to the above (and that they were "Yes", "Yes", "Yes", "Yes", "No", "Almost nothing unless you're incredibly perf-sensitive", and "No".), but I've been trying to diagnose a bug which appears to contradict these beliefs.

IDisposable and garbage collection are unrelated, except for the one situation where an object implements a finalizer that happens to call .Dispose().
Unless you know for sure, 100%, and explicitly, that an object has a finalizer that calls .Dispose() then you must call .Dispose() explicitly (or with a using) to ensure the object is disposed.
The answers to your questions:
Yes.
Yes.
Yes.
Yes.
No.
No.
No.

Related

Why do enumerators need to be disposed? [duplicate]

This question already has answers here:
Why does IEnumerator<T> inherit from IDisposable while the non-generic IEnumerator does not?
(6 answers)
Do I need to consider disposing of any IEnumerable<T> I use?
(1 answer)
Closed 1 year ago.
According to the accepted answer to Enumerator disposal when not using using, foreach or manually calling Dispose() enumerators in C# must be disposed when finished with, whether you let foreach do this automatically, or do it yourself if you prefer to write out the equivalent logic by hand.
I wasn't expecting this; would have thought enumerators would be handled by the garbage collector. I'm guessing it's along the lines of:
Database queries are also enumerable, and those need to be disposed because they could be holding database connections, which are a scarcer resource than memory.
To correctly handle this case, the framework designers decided to just make enumerators implement IDisposable, so the contract is they should always be disposed; for in-memory collections like strings, arrays and lists, this will be a no-op, but it makes the overall design simpler than trying to make some kinds of enumerators implement a different interface.
Is this correct, or am I missing something?

Does C# stores references to tasks from TPL [duplicate]

This question already has answers here:
Can .NET Task instances go out of scope during run?
(2 answers)
Closed 8 years ago.
Lets assume I run such a code
Task.Factory.StartNew(...).ContinueWith(...);
I don't store reference for neither of two created tasks so can I be sure that they won't be disposed before starting or at the process of executing? If yes then where do reference to these tasks are being held?
A reference to a TPL Task is held by the system under two conditions:
The Task is scheduled
The Task is running
Upon completion of the Task and any child tasks, the reference is thrown away. References in your code will behave as expected.
I believe you have some confusion regarding garbage collection and Dispose. This question may enlighten you.
Difference between destructor, dispose and finalize method
Destructor implicitly calls the Finalize method, they are technically same. Dispose is available with those object which
implements IDisposable interface...
Should you dispose Tasks?
Stephen Toub says:
No. Don’t bother disposing of your tasks.
https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/

What is a function that has a ~ before the function declaration? [duplicate]

This question already has answers here:
What does the tilde before a function name mean in C#?
(6 answers)
Closed 9 years ago.
So i bumped in to this:
Public Stam {
public Stam() {Console.WriteLine("Stam");}
~Stam(){Console.WriteLine("Stam")}
}
What exactly is the ~? and what will happen when i call the Stam class.
The ~ operator, in this circumstance, is being used to denote the class destructor, destructors are called automatically as part of the cleanup process.
However, the ~ can also be used for bitwise complement operation.
It is a destructor for the class. It is called automatically when an instance of the class is deleted, you use it to delete objects etc.
In C# it's called Destructor, the equivalent to a C++ destructor is IDisposable and the Dispose() method, often used in a using block.
See System.IDisposable from MSDN
What you are calling a destructor is better known as a Finalizer.
generally destructor function/methods are declared like this.
Your call seems like a finalizer.

Dispose Finalize and Destructors [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Finalize vs Dispose
Dispose - This will free up the object memory and GC should be supperessed in this case.
Finalize - In case the object is not disposed and when then object goes out of the scope(I mean when the class goes out of the scope) GC will say Finalize to clean it up.
Destructor - Don't know. Can you explain difference b/w destructors and finalize ?
Dispose cannot free up memory. The Dispose() method releases or closes the unmanaged resources.
Finalize
It is used by the Garbage Collector implicitly to free the space.
Destructor
It is used to destroy the variable's value.
The destructor implicitly calls finalize, so it is sort of a pre-finalize.
See MSDN for more details. One important tidbit from that documentation:
Even with this explicit control over resources, the destructor becomes a safeguard to clean up resources if the call to the Dispose method failed.
Descrtuctor is in c++ and Finalizers are in .NET. Althought the way your represent a finalizer in C# code looks like a C++ descructor, but it's not the same and its behavior is different too.
Finalization is the last process that happens in .NET memory management. Disposing is the pattern one cleans up unmanaged memory. Remember that Dispose is the operation carried out manually or explicitly called basis, whereas finalizer is not. It's automatic by the run time.
You may wish to read this

How does .Dispose() work in C#? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Proper use of the IDisposable interface
When is Dispose necessary?
If I write a class, which uses graphics, or threads for example, must I implement the IDisposable interface to write a Dispose() method or else memory leak occurs?
Does Dipose() run when the GC reaches it?
If I implement a Dispose() method, shall I call Dispose() on all the disposable fields in the class when "disposing" parameter is true, or is it automatic?
What is "unmanaged resource"?
So I'm pretty unsure about it, I'd appreciate anything that helps me understand these things :)
Thank You
IDisposable is just a pattern to follow. It doesn't do anything, in and of itself, special (other than fitting the requirements of the using statement).
If you're working with a native resource, the resource isn't "known" to the garbage collector. IDisposable is the convention used to allow you to free this resource deterministically.
For details, I wrote a detailed series on IDisposable which talks about why and how to implement it for various scenarios (including wrapping a native resource, encapsulating other IDispsable types, etc).

Categories