Sometimes I see people like to dispose just anything after use regardless of how frequently they're being used (probably not related to SQLite question, but I am dealing with SQLite as of now, I'm puzzled) -- or perhaps I am mistaken. This has caused a massive confusion for me.
For example (taken from elsewhere):
using(var con = new SQLiteConnection(conString))
using(var cmd = new SQLiteCommand(con))
{
con.Open();
// ...
} // also closes the connection
My question is, should I store the SQLiteConnection and SQLiteCommand objects in the field, and use the method .Open(), .Close() to handle the database connection without disposing them at all until application termination -- or dispose them into the Garbage Collection like it's not really an elegant idea in my perspective?
Edit: If one says dispose, then why? I need better answers, I need the true reason why, not because of pooling, and whatnot. I need to know what exact problems could arise other than human-prone errors, and provide an example or perhaps a link to the example.
For example the class field:
private static SQLiteConnection sQLiteConnection; /// <summary>SQLiteConnection.</summary>
public static SQLiteConnection SQLiteConnection { get { return sQLiteConnection; } }
private static SQLiteCommand sQLiteCommand; /// <summary>SQLiteCommand.</summary>
public static SQLiteCommand SQLiteCommand { get { return sQLiteCommand; } }
Where the private fields are initialized with a private method, and the objects are to be reused without disposing them; Hence the read-only properties.
Edit 2: For clearer clarification, are you people misreading? I am saying "reusing". Which means one is created, and stored somewhere in the field to be reused. I am storing it in the static field in a static class to be reused until the application is closed. Tell me, why do I have to dispose it?
Why, do, I, have, to, dispose, it? If, I, were, to, "reuse", it? Why?
Connections are pooled by .NET, so creating them generally isn't an expensive operation. Using the "standard" approach is generally much cleaner that trying to keep track of if a connection is open or closed, etc.
Unless you have measurable problems with connection I would stick with the idomatic approach of creating them, using them, and disposing of them.
Related
I want to re-use the same SQLConnection accros different methods within the class. What I'm doing right now (testing only) is creating and opening a connection in the constructor:
SQLConnection Connection;
Constructor(string connection_string)
{
this.Connection = new SqlConnection(connection_string);
this.Connection.Open();
}
then I use "this.Connection" inside methods and finally use this.Connection.Close() and Dispose() at the end when the object is not needed anymore. From what I know it would be cleaner to use 'using' inside each method like this (the constructor would only set the connection_string):
using (SqlConnection connection = new SqlConnection(connection_string)) {
connection.Open(); ...
}
Because of connection pooling, only one connection is actually used, despite the above 'using' line being placed in multiple methods (e.g. when they are called one after another), correct? However, wouldn't this create many SQLConnection instances where only one would be needed? E.g.:
MyClass obj(some_string);
obj.Method1(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method2(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method3(); // calls 'using SqlConnection connection = new SqlConnection'
So what's the proper, optimal way to share the SQLConnection?
You are correct about all your statements. However you are missing one important point: creating lots of instances of a type in .NET is not necessarily a bad thing!
You should not create a single connection instance in the constructor
You should create a connection locally, when needed
It is best practice to use the using paradigm when creating disposable objects
You should make a habit of calling Dispose on disposable objects in a try...finall block (if not using using) - in case your specific scenario doesn't land itself well for the use of usings; for instance using asynchronous methods)
Finally, you should not keep a SQL connection open for longer than you need it to be. Again, just take advantage of connection pooling in the ADO.NET provider for SQL Server
Now, the reason it's not a problem to create lots of instances of the Connection type is because creating objects in the .NET CLR is optimized (fast memory allocation and object instantiation) and relatively pain free (no need to worry about releasing memory thanks to Garbage Collection).. You also have the benefits of connection pooling in case of the ADO.NET providers so really, you shouldn't concern yourself with managing the number of instances of this Type.
It should be obvious that in other cases (such as heavy/large objects) creating lots of them can have an impact on memory pressure and performance. So always asses the situation as best as you can..
I am using ASP.NET 4.0.
From last few weeks, few users are complaining that the application starts malfunctioning. The GridView suddenly starts showing contents of a DropDown control that the same user or another concurrent user might have accessed at any point of time in that day. Similarly, DropDown controls may get populated by RowID of the any old result-set instead of the actual items.
I came across an article: Users seeing other users data in ASP.NET where the author discusses about Static objects responsible for memory leak behavior.
It reminds me of a class in my project which is Static and contains public static methods. This class contains methods to populate a DropDown, return a DataSet for a query input or return a scalar object based on a query input.
Extract of this class is below:
public static class reuse
{
public static void FillDropDownList(string Query, DropDownList DropDownName, string ConnectionStringParameter)
{
SqlDataReader dr;
try
{
dbConnection.OpenConnection(ConnectionStringParameter);
//Check whether the Drop Down has existing items. If YES, empty it.
if (DropDownName.Items.Count > 0)
DropDownName.Items.Clear();
SqlCommand cmd = new SqlCommand(Query,dbConnection.cn);
dr = cmd.ExecuteReader();
DropDownName.Items.Add("-- Select --");
DropDownName.Items.Add("All");
while (dr.Read())
DropDownName.Items.Add(dr[0].ToString());
dr.Close();
}
catch (Exception ex)
{
rpkCustomErrorHandler.GetScript(HttpContext.Current.Response,ex.Message.ToString());
}
dbConnection.CloseConnection();
}
}
I want to know whether this is the cause of the malfunction I discussed above. If yes, is there any way to dispose Static Methods after the task of the method has finished. Do I need to change the class from Static to a default plain class?
Edited
I have another class which is also static and is used by the above class:
public static class dbConnection
{
public static SqlConnection cn = new SqlConnection();
public static void OpenConnection()
{
try
{
cn.ConnectionString = ConfigurationManager.ConnectionStrings["cnWebTwDrill"].ToString();
if (cn.State == ConnectionState.Closed)
cn.Open();
}
catch (Exception)
{
throw;
}
}
}
Shall I remove "Static" from the Connection Class and make call to this class by using a unique instance each time?
The code you've shown us is an example of bad usage of static class/method. You put in a static method or class things that are to simple to fit in an object AND which DON'T REQUIRE state.
The functionality you have there should be split between the Business Layer (which will retrieve the data) and the UI/COntroller (in this case Page ) where you assign the data to the server control. All this operations are specific to a request, there is no reason to use a static method for that. Is just a sign of (bad) procedural programming. And when dealing with db access (or disposable objects) you should use the using statement. Something like this
using(var conex=GetConnection())
{
try
{
conex.Open();
//do stuff
var cmd= new SqlCommand();//cfg command
using (var rd= cmd.ExecuteReader())
{
//do read
}
}
catch(Exception ex)
{
//handle exception
}
}
The using statement automatically calls Dispose at the end of the block. It's basically a shortcut for
try {}
finally{ //dispose }.
Its not a question of leaking or disposing its a question of utilizing static objects with state. This function is static, but it is not statefull all of the context of the operation is present in the call as such all of the objects in this class that are not parameters will be cleaned up automatically. However if you defined some type of static data any users in the same app domain would share the value. That being said you must be carefully any time you utilize statics as they are hard to test replace and are very difficult in multithreading situations.
I doubt the error you're seeing is caused by a memory leak or a failure to Dispose of static objects.
However, to answer your question: the only way to free the memory held by static objects is to set the associated static references to null. After that, they won't be reachable, and the GC will take care of the rest.
Two things that might help with the actual problem:
Faulty caching strategies can cause unintentional data sharing (at the HTTP level or with the ASP.NET object cache, output caching, etc)
Be sure to use locking around all references to static objects that can be shared between threads, where one thread might write the object while another is reading it.
BTW, the static method in the OP does not appear to use any static objects; everything it touches seems to be passed as an argument. Static methods alone don't allocate or hold memory references.
Update:
Trying to share a single DB connection between page requests is a bug, and will almost certainly result in undefined behavior (for example, one page could issue a query, while another page reads the response). DB connections are already pooled by the runtime; you don't need to optimize that part on your own. Each page request should not only use a new SqlConnection, it should also call Dispose() on the connection object afterwards, to promptly release it back to the pool.
I recently posted (and promptly deleted, when I decided the question was irrelevant to the actual problem) a question about SqlConnection losing its Database information when the scope of "ChangeDatabase" ends. Example:
//Other code...
dbConn = new SqlConnection(dbConnBuilder.ConnectionString);
dbConn.Open();
dbConn.ChangeDatabase(currentDatabase);
dbConn.Close();
}
My questions:
Is it considered bad practice to hold onto a SqlConnection object and open and close it whenever you need it when you'll only ever have ONE connection of a given type?
Why does dbConn.Database not remember currentDatabase after ChangeDatabase (a method not a variable) 'Goes out of scope'? (Heck, I didn't know methods like ChangeDatabase could know about scope).
My connection string was:
Data Source=server.name.com;Persist Security Info=True;User ID=username;Password=password
Thanks guys, let me know if I can give you more information, still learning to use S.O.
Calling Close() completely destroys the object, so you should not be reading any of its properties after.
In fact, there should even be an "after" because you shouldn't be calling Close(). Instead, instantiate the connection in a using block, so that it'll call Dispose(), which does the same thing as Close(), but is guaranteed to do so no matter how you leave the block.
So just make sure to call changedatabase every time you need to execute a statement :-)
I am using the .xsd dataset thingies (which I hate) to auto-generate TableAdapter classes for some backend code.
I have not really used these before, tending to favour manual commands and stored procs whenever possible (for various speed-induced reasons: those xsds play hell with dynamic tables and really large amounts of columns), and am finding myself instantiating a TableAdapter in a large number of my methods, so my question is this:
Will the auto-generated code automatically streamline itself so that a full adapter class is not created on an instatiation, and instead share some static data (such as connection information), and if not would it be better for me to have some sort of singleton/static class provider that can give me access to their methods when needed without the overhead of creating a new adapter every time I want to get some information?
Cheers, Ed
If you're concerned about the performance you could always run a benchmark to see what the performance hit, if any, is.
Sorry you didn't find my answer useful.
My point was that while you had received responses they all seemed to be subjective and not based on hard data. So if you had some reason to be concerned that there was a performance hit in your particular application you should measure it.
There is no reason to refactor one area for performance unless there is an actual problem.
I actually tend to instanciate a very low number of adapters (usually only one of each type). I never tried using them as on the stack variables (instantiated when needed), so I never ran into your question, but I understand your concern.
From what I know the aqdapters themselves may be quite heavyweight in instancing, but the real killer is the connection. What I do is I mark the adapter's Connection modifier as Public in the .xsd designer so I can assign the property whatever I need it to use, and maintain a tight grip on the opening and closing of connections:
void Load() {
using (SqlConnection conn = ...) {
conn.Open();
invoicesAdapter.Connection = conn;
customersAdapter.Connection = conn;
invoicesAdapter.Fill(dataSet.Invoices);
customersAdapter.Fill(dataSet.Customers);
}
}
void Save() {
using (SqlConnection conn = ...) {
conn.Open();
invoicesAdapter.Connection = conn;
customersAdapter.Connection = conn;
invoicesAdapter.Update(dataSet);
customersAdapater.Update(dataSet);
}
}
I ommitted transaction control and error handling for brevity.
public class db
{
public static string connectionString =
WebConfigurationManager.ConnectionStrings["connectString"].ConnectionString;
public static SqlConnection OpenConnection()
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
return connection;
}
}
I see code like this and it screams WRONG! It's for an ASP.NET (2.0). I understand it to be wrong.
For one you shouldn't open the SqlConnection and return it and two why would you make a static SqlConnection? Won't that create problems if multiple people are trying use it at the same time?
What is static is OpenConnection() the Method which returns the connection. A new connection gets returned each time however (the assumption is that caller will be in charge of disposing of this connection object when appropriate).
In other words, the db class shown is not a singleton at all. The confusion may arise from the fact that one does not need to instantiate an instance of db in order to use its OpenConnection() method (since it is static), and the rest of the code may contain multiple snippets like
myConn = db.OpenConnection();
-- then do something with myConn
I'm not 100% sure what the question is, but to answer this
Won't that create problems if multiple
people are trying use it at the same
time?
no, there wouldn't be problems because each call to OpenConnection() constructs a new SqlConnection instance. That doesn't mean the code isn't garbage for other reasons. I at least hope calls to this method look something like this:
using(var conn = db.OpenConnection())
{
// stuff
}
You can't just say "Screams of being wrong" and then apply the term "Singleton" incorrectly. Why is a single static connection a poor approach? It you do not recreate it each time, then your entire application can share the connection. Do you need to create, open and close for each frigg'n sql call, that screams of stupid. Either way ADO should manage this.
Connection objects must be scoped to the method that executes the transaction.
Sharing the same connection object between threads will corrupt the connection pool.
See this question on SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange.