I have created a class to store search values to a session. Such that when I get back to the search page from another page, I can get the values stored in the session. When the search page loads, I'm getting the values from the session, fill up the text fields and dispose the object afterwards. But I get a StackOverflowException when I try to dispose the object. Why does this happen and how do I fix it?
public class SearchValue : IDisposable{
public int ID {get; set;}
public string Name {get; set;}
public void Dispose()
{
this.Dispose();
}
}
public void SaveSearchValueToSession()
{
SearchValue searchValue = new SearchValue();
searchValue.ID = Convert.ToInt32(txtID.Text);
searchValue.Name = txtName.Text;
Session["SEARCH_VALUE"] = searchValue;
}
protected void Page_Load(object sender, EventArgs e){
SearchValue searchValue = (SearchValue)Session["SEARCH_VALUE"];
txtID.Text = searchValue.ID.ToString();
txtName.Text = searchValue.Name;
//Right here I would like to dispose the object
searchValue.Dispose()
}
You are calling the same method from inside the Dispose method. This will indeed cause a StackOverflowException. I do wonder if you really need to implement IDisposable and if you understand its purpose...
If you really need to:
Give a meaningful implementation of Dispose, free unmanaged resources, etc;
Use using around the variable;
Don't save it inside the Session after disposal.
Also read the Fundamentals of Garbage Collection.
From comments I notice you are worried of creating too much objects. Don't worry, it is no problem here. This is especially true since your object (single) doesn't get garbage collected now: you save it in the session where it will live until the session is distroyed. You keep reusing the very same object over and over again.
Your problem stems from the improper way to implement the IDisposable pattern. Here is a short but complete example for implementing it:
public class ThisIsDisposable : IDisposable
{
public ThisIsDisposable() { }
private bool _isDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (!_isDisposed)
{
//Do your unmanaged disposing here
_isDisposed = true;
}
}
}
}
If the class is sealed, then the second Dispose(bool) method should be marked private and not virtual. The primary use of IDisposable is to dispose of unmanaged resources. If you don't have unmanaged resources, you can still implement it so that the object can be used in using statements, but generally the Dispose(bool) overload will not do anything in that case.
See CA1063 (https://msdn.microsoft.com/en-us/library/ms244737.aspx) and IDisposable Interface (https://msdn.microsoft.com/library/system.idisposable.aspx)
As your comments have said, using IDisposable will not automatically free memory. Your object will be garbage collected when there are no more references to the object. Storing references to your values and never removing those references will result in a memory leak, so if you want to make sure that you don't leak memory, then you need to make sure that there are no more active references to the objects you create (clear the list/session object,etc).
In your case, it is completely unnecessary to implement this pattern because your objects are not used in using statements and they don not consume managed resources.
Using sessions is a hard battle. Personally, I only EVER use them for account login status. A query string would help you out here. See the example below.
Page Before
Response.Redirect("http://yoursite.com/search?id=12");
Then on the search page (assuming) (Page Load)
// usual if(!Page.PostBack)
int searchId = -1;
if(Request.QueryString.Count > 0)
{
String searchIdStr = Request.QueryString["id"]
if(searchIdStr != String.Empty)
{
try{
searchId = Convert.ToInt32(searchIdStr);
SearchValue searchValue = searchValueRepo.GetSearchValues()
.Find(o => o.ID == searchId);
if(searchValue == null){
//Failed to find your search values
}
} catch (Exception ex) { //failed to convert to integer };
}
}
Then, if you feel that the user has too much control over the query string you can then set id=239847hcjdhnsjk or a salted hash so no one can attempt to change the value to change the behavior of the site.
Related
[There is a similar question Shared ownership of IDisposable objects in C# but the accepted answer suffers from similar design problems which my solution has]
I have been trying to think around this problem having seen many designs taking a blind leap of faith in garbage collector when working in c#. Reason being many times its easy to ignore that one need to handle the IDisposable rather carefully making them close equivalent of resource allocation in c++. I understand that pedantically speaking Dispose is not the equivalent of c++ destructor but if you are holding on to native resources which needs to be cleaned in a deterministic manner it becomes very similar.
But if the object is shared by multiple resources (for eg. an HttpClient object which is meant to be created and used concurrently for performance), who owns the responsibility of calling Dispose since there is no single owner? To solve this problem I came up with a SharedOwner library which has a similar interface as shared_ptr.
Code snippet:
SharedOwner:
public static SharedHandle<T> MakeSharedHandle(Func<T> createSharedOwner)
{
var obj = new SharedHandle<T>(createSharedOwner());
return obj;
}
public SharedHandle(T obj)
{
AddReference();
m_object = obj;
}
public Handle<T> GetHandle()
{
AddReference();
return new Handle<T>(this);
}
internal void Decrement()
{
if (Interlocked.Decrement(ref m_refCounter) == 0)
{
m_object.Dispose();
m_object = default(T);
}
}
internal T GetInternalHandler() { return m_object; }
private void AddReference()
{
Interlocked.Increment(ref m_refCounter);
}
~SharedHandle()
{
m_object.Dispose();
}
Handle
is a transparent wrapper that manages the ref counting calls keeping that abstracted from consumers.
public sealed class Handle<T> : IDisposable where T : IDisposable
{
private SharedHandle<T> m_handle;
bool disposed = false;
internal Handle(SharedHandle<T> handle) { m_handle = handle; }
public void Dispose()
{
if (!disposed)
{
m_handle.Decrement();
GC.SuppressFinalize(this);
disposed = true;
}
}
~Handle()
{
if (!disposed)
{
m_handle.Decrement();
}
}
The typical usage pattern that I imagined would be:
using (var sharedClient = this.m_sharedClient.GetHandle()) // m_sharedClient is the SharedHandle passed
{
var httpClient = (HttpClient)sharedClient;
// use httpClient
}
Now I see two issues with this approach which deviate it from the original motivation of simulating shared_ptr behavior:
The first reference is held by SharedHandle itself. So even when all Handles are out of scope one reference would still be held by SharedHandle thereby making the if block in Decrement unreachable.
The final Dispose happens when the SharedHandle dies which in lot of sense is no better than not calling Dispose on the underlying object itself. Hence making the solution much less valuable.
I am thinking of moving the reference counting to Handle and using SharedHandle as the control block in shared_ptr but then that means that one may end up with a valid SharedHandle object holding on to a Disposed internal object.
Another alternative that I can think of is making SharedHandle derive from IDisposable and just call Decrement in Dispose. But then this brings other set of design issues. Is there anything that can be done to solve this problem in a more elegant way?
all. I've never worked with destructors nor dispose, so this is new to me.
I have a task of doing a class that has destructor and dispose methods, and that has a UInt64 Id property that is auto-incremental, and a static Dictionary<UInt64,MyClass> that must reference by Id all live instances of MyClass.
After searching how to use them properly, this is what I ended up doing:
public class MyClass : IDisposable
{
private static Object Lock = new Object();
private static Dictionary<UInt64, MyClass> LiveInstances = new Dictionary<UInt64, MyClass>();
public UInt64 Id { get; private set; }
public MyClass()
{
lock (Lock)
{
var newId = IncrementalId();
if (newId == 0)
{
throw new ArgumentException("Reached MAX VAL");
}
Id = newId;
LiveInstances.Add(Id, this);
}
}
~MyClass()
{
CleanUpNativeResources();
}
public void Dispose()
{
lock (Lock)
{
CleanUpManagedResources();
CleanUpNativeResources();
GC.SuppressFinalize(this);
}
}
protected virtual void CleanUpManagedResources()
{
LiveInstances.Remove(Id);
}
protected virtual void CleanUpNativeResources()
{
}
private static UInt64 IncrementalId()
{
for (ulong i = 0; i <= Convert.ToUInt64(LiveInstances.Count) ; i++)
{
if (i != UInt64.MaxValue && !LiveInstances.ContainsKey(i + 1))
{
return i+1;
}
}
return 0;
}
}
Now, my question is How do I dispose objects? Whether I try to find examples of disposing objects, I find something like this:
// Code to dispose the managed resources of the class
Console.WriteLine("Object disposed");
Thanks in advance.
Managed resources will be disposed automatically by the garbage collector at some point of time. Unmanaged resources are things like Filehandles, obtained by making a Windows API call that returns a Windows Handle which must be freed manually. You dont have anything which requires manual disposal.
If you don't free those handles, they will remain allocated for the duration of the program, but all .Net classes that have an unmanaged resource provide a Finalizer (see below) to make sure that they will normally be freed at some point.
(But if you were writing your own file handling class and forgot to free the file handle anywhere at all, the file would remain open until your program exited.)
Normally such unmanaged resources will be freed in two places:
The Dispose() method. This should be the normal way that you dispose unmanaged resources.
The Finalizer. This is a last-resort mechanism. If a class has a finalizer it will be called by the Garbage Collector when it cleans up a dead object. Any class which has an unmanaged resource should have a finalizer to clean up if the programmer forgets to call Dispose().
The basic Dispose pattern used goes something like this:
class MyObject : IDisposable
{
//indicates if dispose has already been called
//private bool _disposed = false;
//Finalize method for the object, will call Dispose for us
//to clean up the resources if the user has not called it
~MyObject()
{
//Indicate that the GC called Dispose, not the user
Dispose(false);
}
//This is the public method, it will HOPEFULLY but
//not always be called by users of the class
public void Dispose()
{
//indicate this was NOT called by the Garbage collector
Dispose(true);
//Now we have disposed of all our resources, the GC does not
//need to do anything, stop the finalizer being called
GC.SupressFinalize(this);
}
private void Dispose(bool disposing)
{
//Check to see if we have already disposed the object
//this is necessary because we should be able to call
//Dispose multiple times without throwing an error
if (!disposed)
{
if (disposing)
{
//clean up managed resources
components.Dispose();
}
//clear up any unmanaged resources - this is safe to
//put outside the disposing check because if the user
//called dispose we want to also clean up unmanaged
//resources, if the GC called Dispose then we only
//want to clean up managed resources
}
}
}
I have a class which instantiates a few unity game objects in a scene hierarchy. This class implements IDisposable. Should I handle these game objects as they were managed or unmanaged resources?
I am following the Dispose pattern, so where should I put calls like GameObject.Destroy(myGameObject)?
Thank you
Edit:
Ok, lets say I want to destroy the game objects instantiated by this class when it goes out of scope. How would you proceed then?
Edit 2:
I was testing the dispose. And I have found a solution. It doesnt work automatically, because GameObject.Destroy(myGameObject) cant be called from different thread. It will throw an error CompareBaseObjectsInternal. So, when no longer needed I call myClass.Dispose(). Also it seems irrelevant whether I handle Unity GameObject as managed or unmanaged.
myMain()
{
DisposeTestClass test = new DisposeTestClass();
//...
test.Dispose();
}
class DisposeTestClass : System.IDisposable
{
public GameObject uselessGameobject { get; private set; }
public DisposeTestClass()
{
uselessGameobject = new GameObject("Useless gameobject");
}
#region IDisposable
private bool _disposed;
~DisposeTestClass()
{
Debug.Log("~DisposeTestClass()");
this.Dispose(false);
}
public void Dispose()
{
Debug.Log("Dispose()");
this.Dispose(true);
System.GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
Debug.Log("Dispose(bool)");
if(_disposed)
{
Debug.Log("Disposed. Return.");
return;
}
if(disposing)
{
Debug.Log("Disposing of managed resources...");
// clean up managed resources
/*
if(uselessGameobject != null)
{
GameObject.Destroy(uselessGameobject);
Debug.Log("Game object destroyed.");
}
else
{
Debug.Log("Game object is null.");
}*/
}
Debug.Log("Cleaning up unmanaged resources...");
// clean up unmanaged resources
if(uselessGameobject != null)
{
GameObject.Destroy(uselessGameobject);
Debug.Log("Game object destroyed.");
}
else
{
Debug.Log("Game object is null.");
}
// set the flag
Debug.Log("Setting the disposed flag.");
this._disposed = true;
}
#endregion
}
}
No, you shouldn't implement IDisposable. But you can :).
"so where should I put call GameObject.Destroy(myGameObject)" And when you want your objects to be destroyed? Actually that doesn't matter whether you call myContainer.Dispose() or GameObject.Destroy(gObj).
The only reason to implement IDisposable for you is to write "convient" code like:
using(var container = new MyContainer())
using(var somethingElse = new MyObject())
{
\\Logic for container and somethingElse
}
But in Unity this makes no sense. I can hardly imagine case when in an Update GameObjects are created and then destroyed.
Huh, I think you slightly misunderstood what IDisposable and using statement is used for. You shouldn't implement IDisposable everywhere just to get rid of an object - this is garbage collector role, it knows better when an object shoyld be disposed.
IDisposable and using statement are used as a try/finally statement(of course it is much more complicated under the hood) and ensure that an object is removed/resolved right after it is not used anymore. It is not always a managed/unmanaged resource issue.
Using using statement won't ensure that your game object will be disposed. It all depends on the fact whether there are another objects pointing to it. Since it looks like a root object, I believe it will be held as long as possible by GC. Note that even if GC call Dispose() on your object, as long as it is referenced, it will be stay on the special queue until it is released.
On the other hand if your GameObject is less the Game, more the Object, you shouldn't consider disposing it using IDisposable as long as it is not somehow connected with some connection/file/external resource. GC will claim memory as soon as your object is considered garbage. Just take into consideration, that IDisposable is something which CLR treats a bit different and is not always the way to go.
EDIT
According to your question from edit - basically when a objects goes out of scope, you do nothing - if GC considers it garbage, it will be removed with the closest GC collection that occur. That's why C# is considered managed language and why you do not release memory on your own.
I have the following code:
A disposable class that contains two disposable members.
One of them is being initialized using new() method, and the other using static factory method.
I Also have static code analisys rules, with CA2213 as error.
public class DisposableClass : IDisposable
{
private WebClient m_DisposableMember1;
public WebClient DisposableMember1
{
get
{
if (m_DisposableMember1 == null)
{
m_DisposableMember1 = new WebClient();
}
return m_DisposableMember1;
}
}
private WebClient m_DisposableMember2;
public WebClient DisposableMember2
{
get
{
if (m_DisposableMember2 == null)
{
m_DisposableMember2 = Factory.Create();
}
return m_DisposableMember2;
}
}
#region Finalize/Dispose Pattern
private bool m_IsDisposed = false;
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableClass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!m_IsDisposed)
{
if (disposing)
{
DisposableMember1.Dispose();
// DisposableMember2 in not disposed and not notified by fxCop
}
m_IsDisposed = true;
}
}
#endregion Finalize/Dispose Pattern
}
This is the simple factory class:
public static class Factory
{
public static WebClient Create()
{
return new WebClient();
}
}
When I call the Dispose() method of the DisposableMember1 property, I get CA2213.
When I call the Dispose() method of the m_DisposableMember1 member, I don't get this error.
More over, I don't get this error for m_DisposableMember2 (Wich was initialized using the static factory), and it is not being disposed.
Does anybody familiar with this issue? What can cause this behavior?
CA2213 is not particularly aggressive about identifying fields that ought to be disposed. Amongst other potential problems, it only considers fields that are directly assigned from a constructor invocation. Assignment of a field value via a property or from a source other than a constructor invocation do not result in the target field being included in the pool of "should be disposed" fields by the rule.
You are expecting a bit too much out of the smarts of this tool. That the property is an alias for the field is only obvious to human eyes. It requires pretty sophisticated analysis to let a tool see that. FxCop just doesn't have that kind of horse power. Your code is in fact questionable. If the property was never used by the client code then you'll create the WebClient object and immediately dispose it. Use the field instead, test for null and Dispose().
The problem with the second field is probably induced by the need for the tool to avoid unnecessary warnings. It will only complain if it can determine with absolute certainty that the field is ever initialized. Same kind of lack of smarts here, it can't tell that the factory always returns a non-null reference. Only when it sees the constructor being used in the class itself can it be sure that the field needs to be disposed.
It's a good tool, not perfect.
Here is what I have:
public void FindByID(string id)
{
using (Parser parser = new Parser()) {
if ( parser.LoadUserById(id)) {
ID = parser.FindID();
Name = parser.FindName();
// ...
}
else {
MessageBox.Show("User not found.");
}
} // end using block. parser is disposed so its memory is free to use again.
}
And here is the actual Parser class itself:
public class Parser : IDisposable
{
XDocument doc;
bool userExists = true;
private const string xmlInformationAddress =
"http://www.dreamincode.net/forums/xml.php?showuser={0}";
public bool LoadUserById(string userID)
{
try
{
doc = XDocument.Load(String.Format(xmlInformationAddress, userID));
if (doc.Root.Elements().Any())
{
userExists = true;
return true;
}
else
{
userExists = false;
return false;
}
}
catch (Exception e)
{
doc = new XDocument();
userExists = false;
return false;
}
}
}
It says I'm not implementing the Dispose() method, but I'm not sure what is supposed to go inside of that method.
Well, why do you want to implement IDisposable? If you've got nothing to dispose of (which looks like it's the case here) then clients shouldn't have to call Dispose.
You seem to be under the impression that calling Dispose will free the memory taken by the object. That's the garbage collector's job - Dipose is entirely separate. It's designed to release unmanaged resources such as file handles (including those indirectly held, such as references to Streams).
In this case:
Don't implement IDisposable
Get rid of the using statement in your calling code
Trust the GC :)
Your class doesn't seem like it needs to implement IDisposable. That being said, if you want to understand how and why you would implement it, you could read my series on IDisposable. It goes into how and why (and when) you should implement IDisposable in detail.
In this case, you have no reason to use IDisposable, since your object doesn't hold any native resources. If it used native resources, or encapsulated another class that implemented IDisposable, then, and only then, you should implement IDisposable.
That being said, IDisposable has nothing to do with freeing memory - that's the job of the GC. It's about freeing resources, which can include memory (allocated natively), but more often involves native handles and other resources.
I agree with Jon Skeet. But if you did have something to "dispose" of -
var x = new Parser();
using (x) {
// Do stuff
}