It must be a very dump question but I am wondering if I can use a cached object as part of the using statement
e.g
using(Class1 sample = Cache.GetClass<Class1>())
Cache.class is a static class which uses memoryCache to store a copy of Class1, and the GetClass is to get a copy of the stored object from cache if it is already there.
In my real life (almost, but simpilfied) exmaple, I have got this:
using (dataDesignerClass dds = Cache.GetClass<dataDesignerClass>()){
...
Dataset ds = new Dataset();
dds.dataadapter1.fill(ds); //dds is the data designer which contains all the sqlconnection, sql commands, adapters..etc which can get quite big
...
}
..which seems to be ok to me, but I find that SOMETIMES the dataset (ds) is not filled by the dataadapter1, without returning error.
My GetClass static class:
public static T GetClass<T> () where T: class
{
string keyName = "CACHE_" + typeof(T).Name.ToUpper();
CacheItem cacheItem = null;
cacheItem = GetCache(keyName); //a function to return the cache item
if (cacheItem == null)
{
T daClass = Activator.CreateInstance(typeof(T)) as T; //the constructor will call the initilalization routine
AddCache(keyName, daClass);
return daClass;
}
return (T)cacheItem.Value;
}
Can someone explain why it fails?
I think it is a bad idea to use using on something you cache.
The idea behind using is that it disposes all unmanaged memory allocation and handles an object has before it is destructed. You should not use your object after it is disposed. The problem here is it is not your intention to destruct and get rid of the object, hence you save it in a cache!
Also, a DataReader is somewhat of a cursor typed object. It will not like you for reusing it, especially when you use more than one thread.
Disposing the object will most likely break your software and give unexpected and unwanted result. Don't use using in this scenario.
Reusing a shared object is sometimes good practice, but you need to make sure it can be reused. In your program, you are storing a data adapter in the cache and trying to reuse it between different threads, that causes strange results sometimes because the data adapter can't be shared. Imaging two threads get a same instance of your adapter and modify it at the same time! IMO the data adapter is quite lite and you can create a new instance for each db read, it's unnecessary to cache and reuse it, that makes things complex.
Related
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.
I started working recently in a new project where we have thousands of lines of legacy code. We are facing several performance issues. I decided to take a look at the code and saw the following. There's a class:
public class BaseDataAccess
{
private Database dB;
public Database DB
{
get
{
if (dB == null)
{
dB = DatabaseFactory.CreateDatabase();
}
return dB;
}
}
}
And many descendant classes which inherit from the previous base class. Internally, those other classes make use of the DB property, like this:
DataSet ds = DB.ExecuteDataSet(spGetCustomersSortedByAge);
Finally, there's a huge class (5000 lines of code) with tens of methods like the following:
public void ProcessPayments()
{
try
{
List<Employee> employees = new EmployeesDA().SelectAll(null);
foreach (Employee employee in employees)
{
employee.Account = new MovementsDA().SelectAll(employee.Id, DateTime.Now);
...
City city = new CitiesDA().Select(zone.cityId);
...
Management m = new ManagmentDA().Select(city.id);
}
}
catch (Exception ex)
{
...
}
}
Note in the previous method EmployeesDA, MovementsDA, CitiesDA and ManagmentDA all are inheritors of BaseDataAccess and internally use their respective DB properties. Also note they are constantly being instantiated inside foreach loops (many times within 2 levels of nesting).
I think the instantiation itself is suspicious but I'm more concerned about what's going on with the database connections here? Is every DA instantiated opening a new underlying connection? How bad is this code?
As a side note about the solution I was considering in case this code should be fixed: I was considering making every constructor private so the compiler starts complaining about the instantiations and refactor the instantiations with calls to the GetInstance method (singleton pattern) to avoid the recreation of the objects and underlying connections. But, I'm not sure if this could also be dangerous in some way, for example, if the connections may get closed. The current code doesn't have that problem because of the instantiatons happening all the time.
It's a common misconception that object construction is expensive. It's much more expensive than base arithmetic or other machine-level things, but isn't likely the direct source of performance issues.
Using boxed integers for a loop is wasteful for example, but constructing an Employee object in each vs reusing a mutable Employee object isn't going to give meaningful performance advantages.
Many garbage collectors are capable of object memory frame reuse in loops like this. In effect a single object frame is allocated and overwritten on each pass of the loop.
In this specific case there may be a cost if the DA's have significant initialization costs. If that is the case I would refactor the code to create those once outside the loop. I would not use actual static singletons. I would use dependency injection to manage singleton objects if you need it. Static singletons are effectively global variables and are an invitation to stateful coupling and the break down of modularity.
I am using the Memory Management while returning the data like below.
private DataSet ReturnDs()
{
using (DataSet ds = new DataSet())
{
return ds;
}
}
Query - Is there any issue in placing the 'Using' Statement while returning the data? I am Still getting the complete schema as well as the data in the receiving function?
This is definitely a wrong pattern. The only reason that it is working for you now is that DataSet.Dispose() is actually a dummy.
using (DataSet ds = new DataSet())
{
return ds;
} // there is a ds.Dispose() here but it does nothing.
If you replace the DataSet with for instance an Enitity framework DbContext then you would not see any data in the calling function.
In general terms, disposing an object you are about to return is an error: your code hasn't finished with that object, and yo will be handing a broken object to the caller.
So indeed: don't Dispose() that, which means: don't use using on an object you will return. It is up to the caller to dispose it: they are the owner now. Of course, this should ideally be documented in the API.
More generally, though, you need to think about exceptions too. What happens if your method errors? For complex scenarios, you may need something like:
SomeType foo = null;
try {
// initialize and populate foo - this could error half-way through
return foo;
} catch {
if(foo != null) foo.Dispose();
throw;
}
to ensure that the object is disposed correctly in the failure case.
Use the using statement in the calling method, not the method returning the object.
public void Caller()
{
using(DataSet ds = GetDataSet())
{
// code here
}
}
public DataSet GetDataSet()
{
// don't use a using statement here
return ds;
}
The using statement is basically the same as doing this:
DataSet ds = null;
try
{
// code here
}
finally
{
if(ds != null)
{
ds.Dispose();
ds = null;
}
}
So, if you used a using statement in a method that is supposed to return the object in the using statement, it would return a Disposed object (i.e. closed stream, closed dataset, etc...)which means some of the internal objects could be null, or closed. In other words, all of the internal resources would be cleaned up, which is the purpose of implementing IDisposable in the first place. If your application relied upon some of these internal resources to be available, for example when using a Stream object, it would throw an exception.
Also keep in mind that not all finally blocks are written the same. Remember, IDispoable was implemented to clean up any INTERNAL resources and unmanaged objects. Those internal resources may not be needed outside the using statement, so sometimes using the using statement as you have may appear to work properly but it is not recommended, and definately won't work with all objects. If Microsoft decided to change the DataSet object in a future release, disposing of something vital to your application, then your working code would suddenly stop working.
I'm not sure what exactly your question is.
Once the method ends by retunring something, ds.Dispose() will automatically be called.
This means that the DataSet your method returns will already be disposed when your calling method receives it.
as Mert comment, note that you're disposing the object you're return.
but basically, the using is actually a try/finally and the dispose will be called the method return. The effect is depends on the IDisposable implementation for each type. usually, you're not suppose to dispose (kill) the entity you're return to caller that probably gonna use it.
I'm currently having a problem where one of my .Net based windows services is hogging up too much memory.
I'm almost positive it has to do with a caching implementation where I have decided to use a "database" caching technique and the problem is occurring with how I am initially loading up the cache values when the service starts up.
Here's the concept...
Class: Service
Operation: Start
Class: Cacheloader
Operation: LoadCache
Class: DataAccessLayer
Operation: Store_Cache_in_DB
...and don't ask me why but...
A) Cacheloader is "newed" up as a local variable in the Service "start" method.
B) DataAccessLayer is static to the service (Singleton via IOC)
So the code kinda looks like this
Service:
start()
{
_cacheLoader = new Cacheloader(_dataAccessLayer);
_cacheLoader.LoadCache();
}
Cacheloader:
LoadCache()
{
var entities = _dataAccessLayer.FindEntitiesForCache();
_dataAccessLayer.Store_Cache_in_DB(entities);
}
DataAccessLayer:
Store_Cache_in_DB(List<Entity> entities)
{
using(someConnection)
{
stored entities in datatable
pass database to sproc that stores each entity
}
}
So, my concern here is with the "entities" that are passed to the static DataAccessLayer object via the Store_Cache_in_DB method. I'm wondering if somehow the garbage collector will not clean these up because somehow they have been referenced with a static class? If this is the case, would it help to assign the entities to a local variable first as so...
DataAccessLayer:
Store_Cache_in_DB(List<Entity> entities)
{
var cachedEntities = entities;
using(someConnection)
{
stored cachedEntities in datatable
pass database to sproc that stores each entity
}
}
...hopefully this would solve my problem. If this isn't the reason why my memory consumption is so high, are there any other ideas? Again, I'm sure this caching technique is the perpetrator.
Thanks in advance!
If this is the case, would it help to assign the entities to a local variable first as so...
Having a local won't change anything - the same object instance will be reachable by user code.
The only part that might keep this from being garbage collected is what happens here:
using(someConnection)
{
stored cachedEntities in datatable
pass database to sproc that stores each entity
}
If entities are kept in a variable that persists, it will prevent them from being collected later.
If this isn't the reason why my memory consumption is so high, are there any other ideas?
I would recommend running this under a memory profiler, as it will tell you exactly what's holding onto your memory.
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.