How I safely dispose a variable? - c#

What is an alternate/better way I can safely dispose of the variables purge and factory in the following code?
public void Run( string XmlFragment ) {
XmlNode xmlNode = null;
try
{
xmlNode = Common.ConstructXmlNodeFromString(XmlFragment, "Params");
var list = DataList();
foreach (var item in list)
{
var factory = new PurgerFactory(item);
IPurger purge = factory.Purger;
purge.Purge();
purge = null;
factory = null;
}
Common.PurgeEmail(SuccessEmail());
}
catch (Exception ex)
{
string errorMessage = $"Purge Error: {ex.Message}. {Environment.NewLine} Stack Trace: {ex.StackTrace}";
Common.PurgeEmail(FailEmail(errorMessage));
}
}

As I think you know, C# has a garbage collector. So for normal objects that don't access an unmanaged resource, just letting the garbage collector clean them is fine.
If you want to deterministically close a managed resource the primary paradigm is inheriting from IDisposable and a using statement. This will call the Dispose function upon exiting the code block of the using statement.
If you otherwise want to clean stuff up, but you don't care when it happens you can use ~(MyType). This is called when the GC does a GC cycle, this is called the Finalizer. I personally haven't encountered a use-case for this vs IDisposable. But if you just want to make sure say a file, or otherwise is deleted when this email object is Garbage Collected, then it might be a good use case for you.

Your code doesn't indicate whether purge or factory implement IDisposable. If they do, you would call
purge.Dispose();
factory.Dispose();
or use using which ensures that Dispose is called even if the method throws an exception:
using(var factory = new PurgerFactory(item))
{
// do stuff
} // factory is disposed.
What we don't need to do is set variables to null. An object gets garbage collected sometime after there are no longer any references to it. It's true that setting factory = null removes that reference to the object, but the same thing happens anyway when the variable goes out of scope. So it's redundant.
There's really no need to try to force that to happen sooner. It's not like the object will get garbage collected the instant there are no more references to it, so we don't worry so much about that.
In this case, the variables are both declared within the foreach loop, so the references go out of scope immediately after each iteration of the loop. In other words, they already go out of scope right at the point when you're setting them to null.
That's part of what's awesome about .NET. Imagine if we had to set every reference variable to null. We'd need try/catch everywhere to make sure it happened. It would be as if every single object was disposable. What a nightmare. Instead it's handled for us in most normal scenarios so that we don't have to think about it or clutter our code with it.

Related

Object disposal when there is no variable referencing it

I have this code:
Method1(Method2());
However, Method2 returns an object that needs to be disposed. Here is how I can handle this:
using (var x = Method2())
{
await Method1(x);
}
Method1 and Method2 belong to framework and it is not up to me to change them.
I have number of such cases. For example, Method2 creates HTTP request and Methid1 sends it.
Again, both methods belong to library that I cannot change.
I know if I do not dispose object, Garbage Collector will eventually do this. May be not soon.
I am wandering, if may be in case when there is no any variable that references the object (as it will be after Method1 returns), I can count on Garbage Collector to dispose the object immediately, and thus it is ok to use the original short option.
Use the using statement, just like you have shown, yes it is the elegant way
using (var something = Method2())
{
Method1(something);
}
Or if you will
using (var something = Method2())
Method1(something);
Anything else would be unusual and confusing (ie disposing it in your method1)... As pointed out by the comments, unless this was some sort of Command/Query Service, or other Dependency that could be injected with a disposable scope
Also, calling wait on anything is suspicious these days

Declaring and disposing a local variable in a function/method in .Net

Until recently it never really bothered me as to how to best declare and dispose of a local variable but I thought I'd ask once and for all and get some feedback as it's starting to bug me more and more these days.
When creating a function/method that creates a local object, which method is best to create and dispose of the object.
For simplicity sake, assume that the method of the object being called will never generate an exception i.e. ConvertThisToString
private string myFirstFunction()
{
MyDataType myObject = null;
try
{
myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
finally
{
myObject = null;
}
}
or
private string mySecondFunction()
{
MyDataType myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
Are both functions ok and is it just about coding preferences or is there one method that's better than the other? Why?
My opinion is that one always requires the try/catch in order to nullify the object, which might be an overkill of try/catch for nullifying's sake, while the other method doesn't call any explicit way to destroy the object, which might be to reliant on .NET GC to release it from memory.
Should I be using the "using" statement instead?
Well, this is probably an incorrect statement. Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
Thanks for feedback.
Thierry
UPDATED:
Removed the catch block as it caused confusion in my question. Should haven't been there in the first place since I did say, no error would ever occur.
That's very wrong.
Don't swallow exceptions.
Assigning a variable to null at the end of its scope will not help the GC at all.
If your object actually has expensive resources, it should implement IDisposable (correctly!), and you should dispose it using a using statement (but only when you're finished with it!)
You don't need to assign to null. When the object leaves scope, it will automatically be eligible for GC. There is no need to do anything special.
Basically, just write the second, simple version.
Should I be using the "using" statement instead?
If your object is wrapping resources (not memory allocated via new ..., but native resources) and implements IDisposable, then yes, you should use the using statement to guarantee those are cleaned up.
Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
It will become eligible to be collected. At some point in the future, the GC will clean it up, but the time when this happens in indeterminant.
The best approach here is the Using statement.
something like this:
private string myFirstFunction()
{
using(MyDataType myObject = new MyDataType())
{
return myObject.ConvertThisToString();
}
}
this will dispose the object after execution.
As with almost everything, it all depends on what object you are using. If the object you are creating implements IDisposable then you would be best served to place in a using (typically). Outside of that most objects will get cleaned up by the garbage collector. IF you are the producer of a class that accesses COM objects then as the producer you should have provided a away for a proper cleanup, e.g. implement the IDisposable interface and handle the Dispose() correctly. As others have commented swallowing exceptions or even try/catching EVERY method doesn't seem like a reasonable or good idea. If a call you are making has the potential of throwing an exception and you have unmanaged or leaky objects then you should handle via a try/finally or a using (again, if appropriate).
You don't need to use a try/catch/finally to set a variable to null. The .NET GC will clear up any unreferenced classes when a method ends in it's own time.
If you are doing something really intensive (more so than your sample shows) then you can set the variable reference to null as a pointer to the GC that this is no longer referenced. This will only make a difference to your program if you are doing something which ends up marking the variable reference for Gen2 collection and then you do more stuff which prevents the GC collecting your variable (because the scope has not been left - in this case the method).
This is a bit of an extreme case as the .NET GC is designed to remove this aspect of programming from your daily concern, and regardless, it should get cleared up when the scope ends - it might just a bit longer.
You use 'using' if the referenced object implements IDisposable, and you do this typically to release unmanaged resources - though there may be other reasons why a class implements this interface.
Your first method is total overkill... it should just be as described in MySecondFunction(), and just don't swallow exceptions (I'm referring to the empty catch block) like that - because it leads to buggy, unmaintanable code! :)

Using statement usage

If MyClass implements IDisposable interface, will the both given snippets disposes MyClass object correctly? and which method is preferable over the other?
Code 1
public MyModel MethodOne()
{
using (MyClass myClass = new MyClass())
{
var myModel = new MyModel();
myModel.MyModelData = myClass.GetData();
return myModel;
}
}
Code 2
public MyModel MethodTwo()
{
var myData = new MyData();
using (MyClass myClass = new MyClass())
{
myData = myClass.GetData();
}
var myModel = new MyModel();
myModel.MyModelData = myData;
return myModel;
}
It is the same: the object will be disposed in both way.
the using statement is translated by the compiler as a try block which calls Dispose in a finally block.
finally is guaranteed to execute after the try block has finished execution, regardless of its execution path.
Dispose is guaranteed to be called, no matter what.
Reference MSDN
As a style and best practice IMHO it is better to dispose an object as soon as it is not needed anymore because you will free resources earlier and because if Dispose throw an exception you will have your method return anything. and it will be easier to debug.
Update
As KrisVandermotten pointed out there are some cases where the finally block will not execute.
Environment.FailFast
the Uncatchable execeptions
Power Failure
using is translated to try with finally block. Your code
using (MyClass myClass= new MyClass())
{
myData = myClass.GetData();
}
Is the same as
MyClass myClass= new MyClass();
try
{
myData = myClass.GetData();
}
finally
{
if (myClass != null)
((IDisposable)myClass).Dispose();
}
As for which method is preferable, both solutions will work fine. The second one disposes of the object earlier and for that reason is preferable, in many cases. There's no need to hold on to objects, especially if they use external resources.
There are exceptions to that, though. You may want to or need to hold on to an object for longer to achieve your objective, e.g. when using a transaction scope. Also, sometimes the objects derived from the disposable object (as in your case) may become invalid if the originating object is disposed.
In both cases, you can rely on the fact that, if an object of MyClass was constructed and the method completes, the object is also disposed.
In the latter case, the object is constructed later than in the first case, and it is disposed earlier than in the first case, but in both cases it will be disposed.
Which is better? Assuming that a disposable object somehow holds on to something that needs to be freed, and that this holding on to it is expensive, all else being equal, the better approach would be the second.
So why the two caveats above?
"if an object of MyClass was constructed"
In the second case, it is possible that the call to new MyData() throws an exception, and the MyClass object construction is not even attempted. In the first case, constructing this object is the first thing that happens. It may fail, but it will be tried. It may fail in the second case as well of course. And if it fails, there is nothing to be disposed.
"and the method completes"
Nothing will be disposed if you lose power before the dispose can be executed, and there are a few other pathological cases where execution of a finally block is not guaranteed.
IMHO the first version is more concise and therefore better, since the extra time taken before disposing is likely to be negligible. It typically doesn't take long to construct a couple of objects and set a property.
Only if there were a call to "myModel.DoSomethingThaTakesALongTime()" would I consider using the second version.

Should Dispose() ever create new instances of objects?

Using C#.NET 4.0
My company's application makes use of a resource locker to keep records from being edited simultaneously. We use the database to store the start time of a lock as well as the user who acquired the lock. This has led to the following (strange?) implementation of dispose on the resource locker, which happens to be called from a destructor:
protected virtual void Dispose(bool disposing)
{
lock (this)
{
if (lockid.HasValue)
{
this.RefreshDataButtonAction = null;
this.ReadOnlyButtonAction = null;
try
{
**Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("#lockID", lockid.Value);
parameters.Add("#readsToDelete", null);
Object returnObject = dbio2.ExecuteScalar("usp_DeleteResourceLockReads", parameters);**
lockid = null;
}
catch (Exception ex)
{
Logger.WriteError("ResourceLockingController", "DeleteResourceLocks", ex);
}
finally
{
((IDisposable)_staleResourcesForm).Dispose();
_staleResourcesForm = null;
}
}
}
}
I am concerned about the bolded section we because have been logging strange "Handle is not initialized" exceptions from the database call. I read elsewhere that it is not safe to create new objects during Finalize(), but does the same rule apply to dispose()? Are there any possible side effects that accompany creating new objects during Dispose()?
which happens to be called from a destructor
That's the real problem. You cannot assume that the *dbio2" object hasn't been finalized itself. Finalization order is not deterministic in .NET. The outcome would look much like you describe, an internal handle used by the dbase provider will have been released so a "Handle is not initialized" exception is expected. Or the dbio2 object was simply already disposed.
This is especially likely to go wrong at program exit. You'll then also have problem when the 2 second timeout for the finalizer thread, a dbase operation can easily take more.
You simply cannot rely on a finalizer to do this for you. You must check the disposing argument and not call the dbio2.ExecuteScalar() method when it is false. Which probably ends the usefulness of the destructor as well.
Dispose is just a method, like any other method. There are some conventions about things that it should/shouldn't do, but there's nothing from the system's perspective that is wrong with creating objects in a Dispose call.
Making a DB call is a bit concerning to be personally; I wouldn't expect such an expensive and error prone activity to be called in a Dispose method, but that's more of a convention/expectation. The system won't have a problem with that.
Yes, but I would not do so unless the object created is within the local scope of the method. IDisposable is an advertisement that this class has some resource (often an unmanaged resource) that should be freed when the object is no longer used. If your Dispose is being called by your finializer (ie you are not calling the destructor directly, but waiting for the GC to do it) it can be an indication that you should be calling it earlier. You never know when the C# destructor will run, so you may be unnecessarily tying up that resource. It could also be in indication that your class doesn't need to implement IDisposable.
In your case your are using object dbio2 which I assume represents your DB connection. However, since this is called from the destructor how do you know if your connection is still valid? You destructor could an hour after your connection has been lost. You should try to ensure that this Dispose is called while you know the dbio2 object is still in scope.

Variables with function scope

How the CLR handles local variables with function scope in case an exception is thrown.
is it a must to use the finally block or the variable is disposed once the flow leaves the function
below is a small example
protected void FunctionX()
{
List<Employee> lstEmployees;
try
{
lstEmployees= new List<Employee>();
int s = lstEmployees[1].ID; // code intended to throw exception
}
catch (Exception ex)
{
ManageException(ex, ShowMessage); //exception is thrown here
}
finally { lstEmployees= null; } // Is the finally block required to make sure the list is cleaned
}
To answer your specific question, no, the finally block you've listed is not required.
Assigning null to a reference variable does not actually do anything, as garbage collection is non-deterministic. As a simplistic explanation, from time to time, the garbage collector will examine the objects within the heap to determine if there are any active references to them (this is called being "rooted"). If there are no active references, then these references are eligible for garbage collection.
Your assignment to null is not required, as once the function exits, the lstEmployees variable will fall out of scope and will no longer be considered an active reference to the instance that you create within your try block.
There are certain types (both within .NET and in third-party libraries) that implement the IDisposable interface and expose some deterministic cleanup procedures through the Dispose() function. When using these types, you should always call Dispose() when you're finished with the type. In cases where the lifetime of the instance shouldn't extend outside of the lifetime of the function, then you can use a using() { } block, but this is only required if the type implements IDisposable, which List<T> (as you used in your example) does not.
Don't be worried about the objects cleanup, that's why the .NET and most modern languages provide the garbage collection functionality in runtime.
If your object has a handle to unmanaged resource do that cleanup.
Some of the other answers are slightly misleading here.
In fact, the garbage collector has got (almost) nothing to do with the variable lstEmployees. But it never needs to be set to null, neither in normal code flow nor after an exception is thrown.
Setting references to null to free the object they point they point to is almost never required, especially not for local objects.
As a consequence, the garbage collector won’t care about the exception either.
On the other hand, unmanaged resources which aren’t handled by the CG do always require manual cleanup (via the Dispose method of the IDisposable interface). To make sure that such resources are returned after an exception was thrown, you indeed need the finally clause. Or, if you don’t intend to handle the exception locally, you can replace the try … finally by a using clause:
using (someUnmanagedResource) {
// … use the resource …
}
// Will implicitly call someUnmanagedResource.Dispose() *whatever happens*!
.NET languages are garbage collected, which means that objects lifetimes are kept track of, so the garbage collection will get rid of your list when it finds no more object references to it.
Not at all. When the variable is out of scope, the garbage collector will take care of it (when the GC decides it's time to collect all the garbage...)
The only thing you have to take in account is that maybe you don't want to wait for the GC to do its job, so resources help by an instance of a class are released (e.g. imagine you have locally created an instance that hols a reference to a database connection. The connection will be held until GC takes care of deleting the instance, and later on deleting the referenced connection, which may take a while).
In these cases, take a look at the IDisposable interface, so you can proactively free resources before your instances are removed by the GC.
.NET's garbage collector will handle this for you. In fact, setting "lastEmployees" to null accomplishes the same thing as just exiting the function.
Any item that is no longer referenced by the root application in one form or another will be marked for collection.
In .NET, you never need to worry about cleaning up managed resource. Hence, managed.
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

Categories

Resources