Is it a good practice to pass IDisposable as a parameter to a method and dispose it inside that method. This is sort of inevitable when you have to use several threads. Well, the best practices says the owner(caller) should dispose it.
E.g.
public void MyMethod(MyClass reader){
using(reader){
//some code
}
}
What if the owner (creating thread) no longer exist? E.g.
interface IReader : IDisposable {
string Read();
}
public class MyReader : IReader {
public string Read()
{
return "hellow world";
}
public void Dispose()
{
//dispose code
}
}
Here you find the problem...
public void Start() {
MyReader[] readerSet = new MyReader[5];
for (int i = 0; i < readerSet.Length; i++) {
readerSet[i] = new MyReader();
}
foreach (IReader reader in readerSet) {
ThreadPool.QueueUserWorkItem(new WaitCallback(Run), reader);
}
//exit after creating threads
}
public void Run(Object objReader) {
IReader reader = (IReader)objReader;
using (reader) {
//use the reader
}
}
IDisposable. Dispose is not called. By default, the garbage collector will automatically call an object's finalizer prior to reclaiming its memory. However, once the System.
If you access unmanaged resources (e.g. files, database connections etc.) in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed.
You never know when the garbage collector will collect your object. You don't even know if it even will (unlike using delete in C++, which is deterministic). So IDisposable is there for deterministically releasing unneeded references (and releasing unmanaged resources).
Implement the dispose pattern for a derived class Instead, to clean up a derived class, you provide the following: A protected override void Dispose(bool) method that overrides the base class method and performs the actual cleanup of the derived class. This method must also call the base. Dispose(bool) ( MyBase.
I think you would be better off taking a creation delegate to guarantee disposal of the object.
Example
public void Start() {
var makeReader = new Func<IReader>(() => new MyReader());
for (int i = 0; i < 5; i++) {
ThreadPool.QueueUserWorkItem(Run, makeReader);
}
}
public void Run(Object state) {
var makeReader = (Func<IReader>)state;
using (var reader = makeReader()) {
//use the reader
}
}
No, the owner should dispose it. The owner is usually an object that created IDisposable instance in the first place. You can read about IDisposable best practices here.
Do transitively dispose of any disposable fields defined in your type from your Dispose method. You should call Dispose() on any fields whose lifecycle your object controls. For example, consider a case where your object owns a private TextReader field. In your type's Dispose, you should call the TextReader object's Dispose, which will in turn dispose of its disposable fields (Stream and Encoding, for example), and so on. If implemented inside a Dispose(bool disposing) method, this should only occur if the disposing parameter is true—touching other managed objects is not allowed during finalization. Additionally, if your object doesn’t own a given disposable object, it should not attempt to dispose of it, as other code could still rely on it being active. Both of these could lead to subtle-to-detect bugs.
It may be a good idea to minimize passing IDisposable instances around so that you don't have to think about owners too much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With