I have seen examples where someone is doing:
IDbConnection db = new MySqlConnection(conn);
var people = db.Query<People>("SELECT * FROM PEOPLE").ToList();
or is the above a bad practice and should all queries be put in using statements like so:
using (var db = new MySqlConnection(conn))
{
var people = db.Query<People>("SELECT * FROM PEOPLE").ToList();
}
As others have correctly noted, the best practice in general is to use using any time an object implements IDisposable and you know that the lifetime of the object is going to be short -- that is, not longer than the duration of the current method. Doing so ensures that scarce operating system resources are cleaned up in a timely manner. Even if an object's disposal is "backstopped" by its finalizer, you don't want to be in a situation where, say, you have a lock on a file or database or something that is not going to be released until the finalizer runs several billion nanoseconds from now.
However I would temper that advice by saying that there are a small number of types that implement IDisposable for reasons other than timely disposal of unmanaged resources. In some very specific cases you can safely skip the using. However, it is almost never wrong to use using, even when it is not strictly speaking necessary, so my advice to you is to err on the side of caution and over-use, rather than under-use using.
Dapper doesn't have a view on this; what you are using here is the database connection. If you have finished with the connection: you have finished with the connection. Basically, yes, you should probably be using using.
The main purpose use of using statments is to release unmanaged resources.When an object is no longer used The garbage collector automatically releases the memory allocated to it but sometimes the garbage collector does not release resources such as files, streams or db connection like in your example.
Think of it of a way to explicitly dispose objects rather than leave it up to the compiler so you can say it's better practice.
In my experience with Sql Server and Oracle (using the ODP.Net drivers and the MS drivers), you need to use using around Connections, Commands and Transactions or you will soon exhaust your connection pool if you do anything but the simplest database interaction in a production environment (the connection pool is typically ~50 - 200 connections).
You may not notice the behaviour in a development environment because debug = a lot of restarts, which clears the pool.
As Eric Lippert above said, it is good practice in general to use using around IDisposable objects.
In practice, you can skip "using" on Parameters for SqlServer and Oracle.
Related
Uses of "using" in C# has a nice explanation of the utilities of the using feature.
.Net has its garbage collector. How does it handle the lack of a dipose()?
Specifically for DB connections, statements and resultsets, is it required a using() for each of them? What happens if they are left behind with no using(), dispose() and neither close()?
Update: the context is web applications, therefore there may be thousands of simultaneous users, each with his own connection/stmt/rs and the app will never be closed.
Since using is a shorthand for calling Dispose, you could imitate it with try/finally. So the real question is what's the consequence of not calling Dispose at all.
Although C# has garbage collection which would eventually release resources most of the time, you want the release of critical resources to happen as soon as you are done with them. If you use using or the equivalent try/finally, the resources would be released quickly. If you let the garbage collector to release the resources for you, your program may be starved of resources while they are "in custody" of GC (i.e. your program is no longer using them, but GC has not released them yet). Moreover, since GC offers no hard guarantee of running finalizers, some resources may not get released explicitly until your program ends, which may cause resource starvation of other processes.
You don't know when .net's garbage collector is called and run, so it's allowing you to do it yourself when you don't need it. So, when your code gets out of using() it's dispose object used in using() instead of waiting for GC to run on its own schedule.
If you don't use with DB connection, then GC will dispose it on its own way based on criteria of algorithm it's implementing. It might get too late(in terms of computer clock) to sweep it.
Garbage collector is a background thread which doesn't run every millisecond. It has specific schedule and its own algorithm which tends it to work on a specific time. E.g., some GC algorithms check for objects having no references then they sweep those objects when GC runs.
Specifically for DB connections, statements and resultsets, is it
required a using() for each of them? What happens if they are left
behind with no using(), dispose() and neither close()?
Actually the worst consequence of a memory leak is holding some memory until you restart the PC. However in this case probably the worst consequence is leaking memory until you restart the application.
If memory growth increases up to where GC cannot clean any longer, in fact if Gen 2 of Small Object Heap is overflow (Large object heap also can overflow), it will throw out of memory exception and close the application.
.Net has its garbage collector. How does it handle the lack of a
dipose()?
All the standard database connection related classes have implement Dispose and Finalize methods properly. Generally there are unmanaged resources in those classes. Unmanaged resources are the resouces (eg: file handlers, database connection handlers and etc) which could cause worse memory leaks that may hold memory until you restart the PC. However, that's where GC's finalization comes handy. If you don't call the Dispose for such Disposable object, garbage collector will execute the Finalize method(if there is a ~destructor) and clear unmanaged resources.
That's the reason why it is required to implement IDispose Pattern properly Dispose and Finalization as required. Finalization is required only if it has Unamanged resources.
The most likely consequence of failing to promptly Dispose database objects is that the program will ask a database server to open a database connections on its behalf with a promise that it will tell the server when they are no longer needed (i.e. close them), but may leave the connections open for quite awhile after they're no longer needed. Such behavior may increase the number of connections the database server will need to keep open simultaneously. Depending upon the server, there may be no consequences, or the extra connections may impair performance, or they may cause some connection requests to get needlessly denied.
Although .NET will try to ensure that database servers will get notified when database objects are abandoned, even if Dispose is not called, the code which uses database objects will generally know when it will no longer need them, long before .NET can determine that they're abandoned. Note also that while some .NET database-related libraries may keep connections open for a little while after a Dispose (so that if code needs the database again it can resume using the earlier connection) such libraries may use timers to limit how long connections are maintained in expectation of further use, rather than depend upon the garbage-collector (which might go a very long time without noticing that an object has been abandoned).
My DBA says that there are way too many connection open and he thinks it is my code in .net that is leaving them open.
I am using LINQ querys and EF code first.
Example Method:
public List<Stuff> GetStuff()
{
var db = new DBContext();
var results = db.stuff.toList();
return results;
}
Do I need to dispose the db var once I am done? My understanding is that I didn't need to in EF and LINQ. Please point me to a Microsoft documentation about managing connection in code or best practices for LINQ/EF and db connections
Update:
I added
db.Connection.Close();
db.Dispose();
and I still see the open connection in SQL after the two lines were executed. Is there a reason why it wouldn't close when I force it to close?
You should listen to your DBA! Yes, use a using. Do not leave connections open unnecessarily. You should connect, do your business with the db, and close that connection, freeing it up for another process. This is especially true in high volume systems.
Edit. Let me further explain with my own experiences here. In low volume processing, it probably isn't an issue, but it's a bad habit not to dispose of something explicitly or not-wrap it in a using when it clearly implements IDisposable.
In high-volume situations, this is just asking for disaster. Sql server will allot so many connections per application (can be specified in the connection string). What happens is processes will spend time waiting for connections to free up if they're not promptly closed. This generally leads to timeouts or deadlocks in some situations.
Sure, you can tweak Sql server connection mgmt and such, but everytime you tweak a setting, you're making a compromise. You must consider backups running, other jobs running, etc. This is why a wise developer will listen to their DBA's warnings. It's not always all about the code...
I just asked this same question over on Programmers.SE. Robert Harvey gave a great answer.
In general, you don't need to use Using statements with Entity Framework data contexts. Lazy collections is one of the reasons why.
I encourage you to read the entire answer on Programmers.SE as well as the links Robert provides in the answer.
The entity framework uses, as far as i know, connection pooling by default to reduce the overhead of creating new connections everytime.
Are the connections closed when you close your application?
If so, you could try to decrease the Max Pool Size in your connection string or disable connection pooling entirely.
See here for a reference of possible options in your connection string.
By default DbContext automatically manages the connection for you. So you shouldn't have to explicitly call Dispose.
Blog post on the subject: Link
But I believe not disposing can cause performance issues if you're processing a lot of requests. You should add a using statement to see whether or not it's causing a problem in your case.
Yes, if your method defines a Unit of Work; no, if something more primitive. (P.S. something somewhere in your code should define a Unit of Work, and that thing should be wrapped in a using (var context = new DbContext()) {} or equivalent.)
And if you belong to the school of thought that your DbContext is your Unit of Work, then you'll always be wrapping that bad boy with a using block: the local caching of data previously fetched during the context lifetime together with the SaveChanges method act as a sort of lightweight transaction, and your Dispose (without calling SaveChanges) is your Rollback (whereas your SaveChanges is your Commit).
Check this out, here's a standard protocol on how to use IDisposable objects.
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
It says:
"As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement."
As they have access to unmanaged resources, you should always consider a "using" statement.
Do I have to use a using statement to dispose immediately even in a method? Or will the ending of the method cause an automatic Dispose of all local variables including graphics?
(I’m asking this because I’ve seen examples that have Dispose calls at the end of methods, and wanted to know if that’s really necessary.)
Thanks.
Yes, you do. Going out of scope does not do anything; it does not call Dispose(), it does not garbage-collect, it does not call a finalizer.
If the type is IDisposable, then yes. It is your job to tidy up after yourself (assuming that the object is actually "done with" at this point).
Possible side-effects of not doing this:
files get left open and cause access-exceptions (FileStream)
connections get left open and cause pool saturation (DbConnection)
unmanaged handles get saturated and cause resource starvation (any winforms/etc)
transactions get left open and cause blocking (TransactionScope / DbTransaction)
etc
basically, bad things.
Furthermore, in most cases where you see Dispose() at the bottom of the method, a using would be preferable. There are some cases where that isn't possible (fields on an object, for example), but the point remains: it sounds like those are bad examples.
You don't ever have to dispose of an object. But if you want to release unmanaged resources earlier rather than whenever the GC gets around to it (which is when it processes the fReachable queue) then yes you should since the scope of of a method does not determine when a disposable object's finalize will be called.
For more you might want to read Jeffrey Richter's Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
As delnan noted if there's a hard limit to the resources you're using you're much more likely to impacted if you let it get reclaimed by the GC rather than calling Dispose. DB connections are a good example of this kind of reasource and is certainly the reason why the NumberOfReclaimedConnections performance counter got created.
Yes, use using. It is a great statement.
Actually if you don't call Dispose (either manually or by using using), you can end up in a situation where your managed memory is stil quite empty, but unmanaged resources are depleted. Eventually it can cause a deadlock because other objects or other processes will wait for your unmanaged resources and you will wait for them. (Garbage collector won't run, because managed memory still won't be full.)
So please call Dispose as soon as you can. Once you don't need an object which has got that method defined, call it.
VS 2010 Beta Code Analysis is advising me to always dispose WCF Service Clients and Data Contexts for LINQ to SQL. Is this advisable? I assume this will eventually happen regardless. What are the pros/cons of doing so implicitly or not at all?
With anything that is IDisposable, it is your job to ensure it gets cleaned up promptly, to close open resources etc (connections, etc). So in short, yes. Finalizers only happen when GC kicks in, which can be a long time - and doesn't allow for the best pooling use etc.
Note however that WCF has a history of dodgy Dispose() implementations, making just using a bit hit-n-miss (you can lose the actual exception). Of course, it is also recommended to use WCF via async methods, which again makes it hard to use using; you'll often need to keep a reference and call Dispose() explicitely in the IO callback.
Re your comments; a few examples:
SqlConnection: if you leave this hanging around (open) you prevent it reusing the connection from a pool; you can ultimately saturate the available connections this way, breaking your app
GDI: IIRC, VS2005 itself (or 2003?) had a bug where an undisposed GDI object; GDI objects don't take much memory, so it didn't trigger GC, but it ran out of available handles and broke (this is a common bug in user code too, but more famous in an IDE)
fail to dispose something like a FileStream: you've blocked your file system
fail to dispose a TransactionScope and you've caused db (etc) blocking
I'd like to know when i should and shouldn't be wrapping things in a USING block.
From what I understand, the compiler translates it into a try/finally, where the finally calls Dispose() on the object.
I always use a USING around database connections and file access, but its more out of habit rather than a 100% understanding. I know you should explicity (or with a using) Dispose() objects which control resources, to ensure they are released instantly rather than whenever the CLR feels like it, but thats where my understanding breaks down.
Are IDisposables not disposed of when they go out of scope?
Do I only need to use a USING when my object makes use of Dispose to tidy itself up?
Thanks
Edit: I know there are a couple of other posts on the USING keyword, but I'm more interested in answers relating the the CLR and exactly whats going on internally
Andrew
No, IDisposable items are not disposed when they go out of scope. It is for precisely this reason that we need IDisposable - for deterministic cleanup.
They will eventually get garbage collected, and if there is a finalizer it will (maybe) be called - but that could be a long time in the future (not good for connection pools etc). Garbage collection is dependent on memory pressure - if nothing wants extra memory, there is no need to run a GC cycle.
Interestingly (perhaps) there are some cases where "using" is a pain - when the offending class throws an exception on Dispose() sometimes. WCF is an offender of this. I have discussed this topic (with a simple workaround) here.
Basically - if the class implements IDisposable, and you own an instance (i.e. you created it or whatever), it is your job to ensure that it gets disposed. That might mean via "using", or it might mean passing it to another piece of code that assumes responsibility.
I've actually seen debug code of the type:
#if DEBUG
~Foo() {
// complain loudly that smoebody forgot to dispose...
}
#endif
(where the Dispose calls GC.SuppressFinalize)
"Are IDisposables not disposed of when
they go out of scope?"
No. If the IDisposable object is finalizable, which is not the same thing, then it will be finalized when it's garbage collected.
Which might be soon or might be almost never.
Jeff Richter's C#/CLR book is very good on all this stuff, and the Framework Design Guidelines book is also useful.
Do I only need to use a USING when my
object makes use of Dispose to tidy
itself up?
You can only use 'using' when the object implements IDisposable. The compiler will object if you try to do otherwise.
To add to the other answers, you should use using (or an explicit Dispose) whenever an object holds any resources other than managed memory. Examples would be things like files, sockets, database connections, or even GDI drawing handles.
The garbage collector would eventually finalise these objects, but only at some unspecified time in the future. You can't rely on it happening in a timely fashion, and you might have run out of that resource in the meantime.