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.
Related
I've been getting a Win32Exception with that infamous error: Error creating window handle. But up until recently, I realized it was happening on a line that tries to call Environment.Exit(0) which I subsequently got rid of, and just let the form close itself.
So my question is, whenever I know I'm not going to need a Form anymore, I always call base.Close() and base.Dispose(true). If I do that, is it really necessary to put the form inside a using block?
It is not really necessary. However, the using block is a handy and fail-safe programming construct. ie. It is common to forget adding the call to dispose. When you choose the 'using' block you never need to worry about disposing the object. So, Its better to practice using the 'using' block for all disposable objects.
You didn't mention about where you placed the call to Dispose method. It should be always in the finally block as explained below.
DisposableClass disposableObj = null;
try
{
disposableObj = new DisposableClass();
....
....
}
finally
{
if( disposableObj != null)
{
disposableObj.Dispose();
}
}
The same above code can be simplified as
using(DisposableClass disposableObj = new DisposableClass())
{
.....
.....
}
Yes. Without using a using, if your code throws an exception for any reason before reaching your explicit Dispose call, your object will not get disposed.
It is not necessary to call Dispose() on an object encapsulated in a using block. However, with respect to your question, it is good practice to encapsulate disposable objects in using blocks, as it ensures that the Dispose() method on that object always gets called.
In any case, this code:
using (var disposableObject = new DisposableObject())
{
// Perform some action...
}
is in practice equivalent to:
try
{
var disposableObject = new DisposableObject();
// Perform some action...
}
finally { disposableObject.Dispose(); }
This is because internally, the using block will always call Dispose() on your object. Actually, as a requirement to implementing the using statement, your object of choice must implement IDisposable in order to even compile.
Adding an additional Dispose() call at the end of a using block is unnecessary and redundant.
Not really. It is basically gives you clearer and concise syntax. Internally, using creates a try..catch..finally block (msdn), which you can replicate if you want i.e.
SomeClass obj = null;
try
{
obj = new SomeClass();
obj.SomeOperation();
}
catch()
{
}
finally
{
if(obj != null)
obj.Dispose();
}
Not sure if there is some need to do that, but why would you do that if you can do it with single using statemenet.
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.
I have a quite large project which I try to keep as clean and tidy as possible. When I run the code analyzer in Visual Studio I get a reliability error which I find quite annoying. I'd really like to learn how to work around it. Here is a simplified example of what I am doing.
Here is the warning.
Warning 1 CA2000 : Microsoft.Reliability : In method 'MyExampleClassForStackOverflow.AddFeed(string)', call System.IDisposable.Dispose on object 'new FeedClassExamle()' before all references to it are out of scope.
Here is my example code:
class MyExampleClassForStackOverflow : IDisposable
{
public ConcurrentDictionary<string, FeedClassExamle> Feeds { get; set; }
public void AddFeed(string id)
{
//The warning is coming from this code block.
//In the full code, the feed classes collects data on a specific
//interval and feeds them back using events.
//I have a bunch of them and they need to be accessible so I
//store them in dictionaries using keys to effeciently find them.
Feeds.TryAdd(id, new FeedClassExamle());
Feeds[id].Start();
}
public void Dispose()
{
foreach (var item in Feeds)
item.Value.Dispose();
}
}
class FeedClassExamle : IDisposable
{
public void Start()
{
}
public void Dispose()
{
}
}
In order to test the code, use:
using (var example = new MyExampleClassForStackOverflow())
{
}
Any suggestion would be welcome.
The warning exists because the code analysis tools can't determine whether the object will get disposed correctly. The way your code is written, the object will not in fact get disposed correctly, but fixing the code will likely not eliminate the warning.
Fundamentally, what needs to happen is for every the AddFeed method to ensure that something will call Dispose on every FeedClassExample instance it creates. The best approach is to avoid creating a FeedClassExample instance if one already exists in the dictonary under the present ID. Failing that, the AddFeed method should either dispose of any FeedClassExample it creates but then decides not to store in the dictionary, or else swap with the one that is in the dictionary (I'm not sure what methods ConcurrentDictionary supports to do that) and then Dispose the old one. The essential requirement is that at all times outside the actual execution of AddFeed, the dictionary will hold all instances of FeedClassExample that have been created but not destroyed.
It may be informative to add a destructor in your FeedClassExample class which does nothing except log a message. If you are calling Dispose on that class correctly, the destructor will never execute. If you fail to call Dispose, it will. Thus, if the destructor ever executes, you can know you're doing something wrong.
The object isn't getting Disposed of if TryAdd fails, so try doing this explicitly:
public void AddFeed(string id)
{
FeedClassExample fce = new FeedClassExamle();
if (!Feeds.TryAdd(id, fce))
{
fce.Dispose();
}
Feeds[id].Start();
}
Only create the instance if it needs to be added:
if (!Feeds.ContainsKey(id)) {
Feeds.GetOrAdd(id, new FeedClassExamle());
}
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 am developing a WCF Data Service. when I try accessing it from the client side, I get this exception :
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Code:
[WebGet]
public IQueryable<Student> GetUsersByClassId(string classId)
{
Check.Argument.IsNotEmptyOrNull(classId, "classId");
using (var db = new schoolContext(connectionString))
{
((IObjectContextAdapter)db).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
((IObjectContextAdapter)db).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var studentQry = from s in db.Student.Include("Class")
where s.Class.Id == classId
select s;
if(studentQry == null)
return new List<Student>().AsQueryable();
else
return studentQry;
}
I suspect the problem is in the code marked ..., which you're not showing.
Make sure to fully evaluate your query before returning it. For example, instead of just doing:
return studentQry;
Try doing:
return studentQry.ToList();
Edit:
Now that you've changed your question to reflect that you're returning IQueryable<T> instead of IEnumerable<T>, there is a separate issue. By returning IQueryable<T> from your method, you're suggesting that the type can be "queried" directly on the server side.
However, WCF is serializing this across the wire, and needs to use a concrete implementation type. IEnumerable<T> is allowed, but not IQueryable<T>. You should switch this to a type that will evaluate fully so the results can be passed correctly.
This is because of Using statement. When your function finishes execution, it disposes object context. When the result IQueryable is enumerated, it tries to use disposed object, so you get the Exception. Remove using, let your sevice implement IDisposable and dispose your object context in IDisposable.Dispose()
Its probably that the client is trying to access a sub property, eg if student.classes is another entity and you try to access it on client. Need to specify include on any sub entities
It is your using that is causing it. The DataContext is being disposed before the linq query evaluates. You can return studentQry.ToList() and see if that works. If that doesn't, try
List<Student> retValue;
retValue = studentQry.ToList();
return retValue;
Finally, it is ugly, but if you don't use a using, you will not have this issue. It should get disposed and cleaned up by garbage collection eventually.