Can session call dispose method on session ending time? - c#

I want to know if IDisposable objects will dispose on session ending.
I know, I can dispose on Session ending event myself. But I want to write an IDisposable class.
For example, I have
public class MyObject : IDisposable
{
// some properties
public void Dispose()
{
// disposing
}
}
and I need to dispose this object on session ending time :
protected void Session_End(object sender, EventArgs e)
{
if (Session["key"] != null)
((MyObject)Session["key"]).Dispose();
}
So, I want to know on session ending time that operation will automatically or I need write as above.

Session_End does not automatically dispose of IDisposable objects, so your Session_End solution is correct.
However:
Session_End is only called when you use "inproc" sessions (but for the other types you would need a serializable object)
It's only called after the session timeout has expired, so you kept this resource for an extra 20 minutes (or whatever your timeout is)
So try and find a solution that doesn't require you to store IDisposable objects in Session.

An instance of a class which implements the IDisposable interface will only be "disposed" whenever you call the Dispose method, whether directly or indirectly via the using construct. It's not something which happens automatically whenever an object falls out of scope.
For example, this would be bad practice;
public void SomeMethodCalledDuringSession()
{
var resourceHog = new ResourceHog(); // where ResourceHog : IDisposable
// Perform operations
}
The object is never disposed properly here, regardless of your ASP.NET session ending. However, you can call Dispose directly when you're finished, or a better idea is to do this;
public void SomeMethodCalledDuringSession()
{
using(var resourceHog = new ResourceHog()) // where ResourceHog : IDisposable
{
// Perform operations
}
}
This translates into a try ... finally pattern, with the call to Dispose in the finally clause, ensuring that it gets called (apart from a few rare situations).
Edit: I would also read this; http://nitoprograms.blogspot.co.uk/2009/08/how-to-implement-idisposable-and.html

Related

How to properly use the dispose method on a class

I'm working on a database and I need to write the database to file when the database class is destroyed along with every else when the form is closed
This is how I'm currently calling it:
class database: IDisposable
{
List<databaseEntry> dDatabase;
public database()
{
dDatabase = new List<databaseEntry>;
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
StreamWriter sw = new StreamWriter(path);
string toWrite;
foreach (databaseEntry dE in dDatabase)
{
toWrite = dE.rfid.ToString() + " " + dE.currentArea.ToString() + " " + dE.itemName;
sw.WriteLine(toWrite);
}
sw.Close();
disposed = true;
}
}//destructor for database (saves database to file)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
The Dispose method isn't called when I close the windows form that this class is open in.
This is for an assignment and I'm not allowed to use SQL for this.
You do not have control over when the Dispose method is called by the garbage collector. If you want to dispose resources when the form is closed, you should manually call the Dispose method when the form is closed.
This is achieved by listening to the FormClosed event of the form.
So you would do something similar to this:
Create this method:
private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
{
if(this.database != null)
this.database.Dispose();
}
Put this line in your form's constructor:
this.FormClosed += Form1_FormClosed;
Since you're implementing IDisposable, another solution would be to wrap your database object instantiation in a using statement - this would automatically call Dispose once the code in the using statement completes.
Syntax for your use case is as follows:
using(database db = new database())
{
//use your db object
} //db is disposed here
Edit:
Matthew Watson’s comment made me realize my answer is over simplified and could be confusing (thanks for the comment Matthew). Here’s (most of) the real story:
All objects have a constructor and a destructor. If these are not specified the default constructor and destructor are used.
Constructor:
ClassName()
Destructor:
~ClassName()
The Constructor is called when you use the new keyword. The Destructor can be called once there is no longer a reference to that specific instance of an object. Notice I said can be called, not is called. Meaning at this point the object is eligible for garbage collection and could be freed when the garage collector runs. I will not go into detail here but just know that the garage collector does not always collect all the unreachable objects for performance reasons. This is one of the key reasons you would want to the IDisposable interface. You can immediately clean up resources when you know they are no longer being used vs. waiting for the GC to clean up the resources. When working with streams or database connections it is a good idea to implement the IDisposable interface.
With that said here is the updated answer (replacing the previous "default Dispose()" references with the destructor reference).
Since this is an assignment I am not going to give you the answer per se, but I'll get you close. The destructor (~database) is normally called by the garage collector when an instance of a database object is no longer reachable. By implementing the IDisposable interface you have provided an alternative to allowing the garage collector to dispose of the object. You are telling the garage collector "I know when and how these resources need to be freed" vs. free these resources when there are no longer references to the objects. But that only applies if you call your Dispose method; more specifically the line:
Dispose(true);
GC.SuppressFinalize(this);
This means "Garage collector, do not call the destructor (~database()) method, I have already handled it".
What you should do in this method is close any streams (StreamWriter) you have open.
Usage: The IDisposable interface has a nice construct in C# the using statement. This is in effect a try catch block where the Dispose method is called in the finally block. StreamWriter also implements IDisposable so you should think about implementing the using statement in your database class. Example:
using(StreamWriter writer = new StreamWriter()){
//do stuff with writer here
}
This is the pattern you should use for your database class in your form. I will let you figure out how to code that up.

Should I dispose a service (layer)-class after I'm done using it?

So I have a service layer in my project which contains all the business logic. It is an MVC project, so when a user calls a page that requires some logic, the service class is instantiated and then used (from the controller). But it will not be used again since a new request will just instantiate a new object again.
Should I dispose these service classes after using them(using a 'using' statement? Or won't I gain any benefit from it since the garbage collector will come not much later anyway?
If this is the case, the same will apply for using my repository objects I guess.
Depends on what kind of resources your service layer are using.
A general rule of thumb:
If anything uses something which implements IDisposable then anything should either implement IDisposable or call Dispose() when done with the something
Why? Let's say that the service layer uses database connections. If you don't dispose them, they will remain open until the garbage collector collects them, leading to a lot of idle connections. That also means that the ADO.NET connection pool have to create new connections for every new HTTP request instead of reusing old ones (when the pool eventually gets empty).
Making sure that IDisposables are disposed is a cheap way of using resources efficiently.
So if you got something like this:
public class MyService
{
public MyRepository _repos = new MyRepository();
// [...]
}
public class MyRepository
{
public SqlConnection _connection = new SqlConnection("...");
// [...]
}
You should start by changing your repos to IDisposable
public class MyRepository : IDisposable
{
public SqlConnection _connection = new SqlConnection("...");
// [...]
public void Dipose()
{
_connection.Dispose();
}
}
Now if we want to follow the rule we either have to dispose the repository inside the methods that use the repos, or implement IDisposable in the service class too. We do the latter since we don't really now when the invoker has finished calling us (the invoker might call two methods in the service).
public class MyService : IDisposable
{
public MyRepository _repos = new MyRepository();
// [...]
public void Dipose()
{
_repos.Dispose();
}
}
finally we can now just do this in the controller to get everything disposed:
public ActionResult Execute()
{
using (var service = new MyService())
{
service.CallA();
service.CallB();
}
}
I do recommend that you follow the Dispose pattern

Why is the Destructor not being called?

I have a very interesting scenario where I would like a class to inform another entity it has been destroyed; however, its not doing what I want it too.
The Problem
The deconstructor, for some reason does not do what its supposed to do.
The Question
Why is the destructor not being invoked and make sure that it does do its necessary clean up.
The Code
So here we have the informer ~
class Connection
{
public const int Port = 50000;// Can be any range between 49152 and 65536
//Teh Constructor
public Boolean Connect()
{
//SetInformation
Information.Id = 545;
using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
{
ContinueConnection.WaitOne();
WebServ.ClientLogin(Information);
}
return true;
}
~Connection()
{
using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
{
WebServ.ClientLogout(Information);
}
}
}
Additional Information
I want the web service to record if the Connection Class is destroyed for any given reason.
When the client is connecting, it works perfectly. The Web Service records every method called from it. If I call ClientLogout explicitly, it will work.
I am aware I can implement IDisposable; however, this object is not intended to be used within the lifetime of one method. In fact, its intended for use for the entire duration of the program and the failure of this object basically results in the failure of the entire project. (Although I suppose main IS a method...)
I need to release a network connection; however, its not in this program, its in another program and unless ClientLogout is called, it won't be released.
My Research
Microsoft says that you should use the deconstructor for the release of unmanaged resources making an explicit reference to network connections. This ones got my quite stumped.
I think you should implement a Dispose pattern for your Connection class, rather than relying on an obscure deconstructor metaphor. This would be the "canonical" way to do it.
public class Connection : IDisposable // <== Inherit from IDisposable interface
{
public const int Port = 50000;// Can be any range between 49152 and 65536
private SomeType webserv; // Use whatever real type is appropriate here.
private Information information = new Information(); // or whatever
// This is a real constructor.
public Connection()
{
//SetInformation
information.Id = 545;
webServ = new ClientSDKSoapClient("ClientSDKSoap"))
webserv.ContinueConnection.WaitOne();
webServ.ClientLogin(information);
}
// Implement IDisposable interface
public void Dispose()
{
webServ.ClientLogout(information);
}
}
And then use it thusly
using (var connection = new Connection())
{
// Use the connection here.
}
The client will be logged out when you leave the using block.
Microsoft says that you should use the deconstructor for the release of unmanaged resources making an explicit reference to network connections. This ones got my quite stumped.
The docs here are misleading. It really just means you need a finalizer somewhere in your object inheritance chain, to ensure that any unmanaged resources are appropriately cleaned up. But you only need this finalizer once for the entire inheritance tree, at the level where the unmanaged resource is first allocated.
As an example, you do not need a destructor or finalizer if you build a class for a data access layer to wrap the SqlConnection type, because the core SqlConnection type already has one. What you should do, though, is implement IDisposable and write code to ensure prompt disposal, so the finalizer on your SqlConnection will be called sooner, rather than later. But if you were to build a whole new database engine that competes with Sql Server, MySql, Oracle, Access, and the like, and were implementing the ADO.Net provider for this new database engine, then would need to write a finalizer for your connection type, because none exists yet.
In this case, ClientSDKSoap type already has a destructor; you do not need to write another.

Cleanly shutting down a DLL's Static events in a host I don't control

Does the following psuedo code accomplish my goal of cleaning up after myself when my DLL is being hosted by code I don't control?
More specifically, how do I clean up my objects created in my static constructor?
Do I need to suppress Finalize in the Disposable?
Am I guaranteed that the compiler or something will call IDisposable even if the Host doesn't?
Psuedo code:
public class MyDLL : SomeHostICantControl, IDisposable
{
public SpinLock MyDictionarySpinlock = new Spinlock; // approximate syntax
public static Dictionary<string, string> MyDictionary = null;
public static Timer MyCleanUpTimer = null;
public static MyDLL()
{
// Set up Cache Here ... how do I dispose of it?
MyDictionary = new Dictionary<string, string>();
// remove old data from the dictionary, use spinlock to sync writes
// or use concurrent dictionary in .NET 4
MyCleanUpTimer = new Timer(); // run every hour
}
// many instances will be created and disposed of. I have no control when or how often
public void MyDll()
{
this.MyHostEvent += New Event Handler....
}
//.. some event handler code here
public void Dispose()
{
this.MyHostEvent -= Event Handler.;
// Do I need to suppressFinalize here?
}
//~MyDll()
//{
// Is this the right place to clean up after my constuctor?
//}
}
Answering your questions in order:
Static fields exist for the lifetime of the application, as such they are "cleaned up" as a result of the application exiting (memory is reclaimed, files are closed etc.). You don't appear to be doing anything that might require explicit action to be taken to clean-up (e.g. flushing buffered data in a StreamWriter to file), but perhaps there are details missing in your code snippet.
You need to suppress finalize in your Dispose() method if your class has a finalizer (yours appears not to as it's commented out), or if someone can derive from your class and may introduce unmanaged resources that may need cleaning up. The latter applies here as your class is not marked sealed, so you should suppress finalize in Dispose().
The runtime will not call Dispose(), however it will call the finalizer if one is present. Note however that as you class instances don't appear to be using any unmanaged resources, a finalizer should not be required.

Why are my connections not closed even if I explicitly dispose of the DataContext?

I encapsulate my linq to sql calls in a repository class which is instantiated in the constructor of my overloaded controller. The constructor of my repository class creates the data context so that for the life of the page load, only one data context is used.
In my destructor of the repository class I explicitly call the dispose of the DataContext though I do not believe this is necessary.
Using performance monitor, if I watch my User Connections count and repeatedly load a page, the number increases once per page load. Connections do not get closed or reused (for about 20 minutes).
I tried putting Pooling=false in my config to see if this had any effect but it did not. In any case with pooling I wouldn't expect a new connection for every load, I would expect it to reuse connections.
I've tried putting a break point in the destructor to make sure the dispose is being hit and sure enough it is. So what's happening?
Some code to illustrate what I said above:
The controller:
public class MyController : Controller
{
protected MyRepository rep;
public MyController ()
{
rep = new MyRepository();
}
}
The repository:
public class MyRepository
{
protected MyDataContext dc;
public MyRepository()
{
dc = getDC();
}
~MyRepository()
{
if (dc != null)
{
//if (dc.Connection.State != System.Data.ConnectionState.Closed)
//{
// dc.Connection.Close();
//}
dc.Dispose();
}
}
// etc
}
Note: I add a number of hints and context information to the DC for auditing purposes. This is essentially why I want one connection per page load
Update:
After having implemented IDisposable on my repository and on my controller class I couldn't find a way to specifically call the Dispose method on my controller as the controller is created and destroyed behind the scenes by the MvcHandler. However I did find that my connections were being closed anyway. I wasn't comfortable knowing that this was working but not knowing why so I did some digging and found an MSDN quote that made me happy:
When execution is complete, the MvcHandler will check if the controller implements the IDisposable interface, and if so, will invoke Dispose on the controller to clean up unmanaged resources.
Final Update:
After a month or so with working this I've now removed all this code and gone down the MS advised route of wrapping a "using" statement around the code in my public repository methods and passing this DC into the private methods. This seems a little wasteful and repetitive as well as resulting in a few more connections being opened and closed. But I was getting linq to sql caching that I could only resolve by resetting the DC.
The correct pattern (short but sufficient version) here is:
public class MyRepository : IDisposable
{
... // everything except the dtor
public void Dispose()
{
if (dc != null)
{
dc.Dispose();
}
}
}
public class MyController : Controller, IDisposable
{
protected MyRepository rep;
public MyController ()
{
rep = new MyRepository();
}
public void Dispose()
{
if (rep!= null)
{
rep.Dispose();
}
}
}
And now you can (should) use MyController with the using clause:
using (var ctl = new MyController ())
{
// use ctl
}
Edit:
Just noticed it cascades to MyController, code added. This shows how indirect ownership of an unmanaged resource spreads out.
Edit 2:
This also correct (as would be a try/finally):
var ctl = GetController ();
using (ctl)
{
// use ctl
}
If you can't keep it local to 1 method, just do your best to call ctl.Dispose() in a Closing event or such.
Destructors are only called by the GC. Your MyRepository should implement the Dispose pattern, and dispose of the dc there.
See this question for more detail. In C# what is the difference between a destructor and a Finalize method in a class?
MyRepository should implement IDisposable, any disposable objects should be disposed of there if you are holding them open for the life time of the object.
Most of the time when you are using a Disposable object you should wrap it in a using block
i.e.
using(var dc = getDC())
{
//do stuff with the dc
}//the dc will be Disposed here
Edit: Link to Language guide for c# destructors
http://msdn.microsoft.com/en-us/library/66x5fx1b(v=VS.100).aspx
I agree with the fact that disposable pieces were incorrect and the suggestions above by Henk Holterman and Darryl Braaten are very good ones i don't think it answers your underlying question.
The answer to your question is that calling Dispose on MyRepository (assuming its an DataContext) does not close the connection. It just returns the connection to the pool for next use.
This SO Post, explains when you should worry about closing connections...

Categories

Resources