I'm changing our DAL to an async DAL.
Looking at :
await _conn.OpenAsync().ConfigureAwait(false);
I see that there's an async method for open connection.But why there's no async method for closing connection ?
A shared connection might used by others
Might return to the connection pool
It is an I/O operation
Possible delayed / time-consuming operation
(I might be wrong about all four above :-))
Question
It seems logic ( to me) that there's should be an async close method for a connection.
Is there a reason why there's not ?
PS I will obviously will use DAPPER at the end , but just for practicing , I've decided to create small mini mini dapper alike DAL.
A shared connection might used by others
Why would this make calling close on it take a long time? If anything this would mean that, in cases where the connection is still being used by others all that "closing" it means is indicating that you no longer needed it, and the actual underlying connection doesn't need to be closed.
It is an I/O operation
Not necessarily. As you said, if it's pooled/shared, then it's just returned to the pool, no IO would happen at all.
And what makes you think that, even if the underlying connection is being closed, that it would take a long time. All that needs to happen is to stop paying attention to the connection, possibly sending a courtesy message through the connection saying that you're done. That's not going to take a long time. You don't need to wait for any type of response to such a message, so you aren't waiting for a completed network round trip in this method.
Possible delayed / time-consuming operation
Why would it be time consuming? If it is delayed (if, for example, the connection is pooled and you're closing it when you're the last user of it) it means that that it'll likely be closed after a bit, but you aren't needing to wait for that.
Marking an object as "no longer in use" simply isn't time consuming, and at the end of the day that's all you're really doing.
In fact, IDbConnection interface (the one required to implement to develop an ADO.NET connection provider along with other interfaces like IDbCommand) doesn't provide OpenAsync.
Thus, OpenAsync is an implementation detail of DBConnection and, for example, it's the base class of System.Data.SqlClient.SqlConnection.
Why there's no CloseAsync? This should be asked to a .NET Framework Development Team member. When there's a design decision like this, usually it's motivated because of some particular requirement either in the framework itself or in some .NET-based solution developed by Microsoft or some partner. Maybe there's a potential question here: Why IDbConnection doesn't define both Open and Close asynchronous flavors? What about an IDbConnectionAsync interface in order to avoid a breaking change with exisiting code?.
BTW, I suspect opening a connection consumes more time than closing it, because closing process can be queued since the caller just expects an OK I'll do it (from the database server) while opening a connection it's not just signaling but an immediate availability of the connection itself.
Since network connectivity might slowdown the connection opening process, it seems like this is the main reason to implement it as an async operation.
Related
I have legacy codes (VB6 Forms) that follow a bad design pattern. It connects to a database in constructor, and close it in the class's destructor (i.e., Class_Terminate for VB6).
There are hundreds of classes that follow this pattern (or use classes which follow this pattern).
We are now migrating it to .NET and met problem. Because when ADO is migrated to ADO.NET (this is a hard requirement), close ADO.NET connection in Finalize method will cause exception.
(More explanation: The exception is : InvalidOperationException: handle is not initialized. Watch into connection object, the State is still Open. From previous questions in StackOverflow, people's suggestion was to Open and Close the connection immediately after usage, and don't keep the connection open for the whole life-time of the class object.)
I've searched and found that in .NET, only unmanaged resources shall be released in Finalize. Object such as DBConnection shall not be closed in Finalize method.
This is a quite embarrassing situation. The best method for us currently is apparently not to Close each connection after usage, and reopen it before usage (it's some kind of time-consuming). We are actually considering to ignore the exception during Close in Finalize method.
I would like to ask,
1) Does DBConnection in ADO.Net implements a Finalize and will close the real underlying connection during GC? If this is true, then ignore close exception in Finalize) won't really do harm to us.
2) If not, will the underlying connections (maybe from connection pool?) be finally returned back to system or connection pool? Say the system or connection pool will check abnormal connection states and retrieve back the resources after some long time?
Thanks.
1) Does DBConnection in ADO.Net implements a Finalize and will close the real underlying connection during GC? If this is true, then ignore close exception in Finalize) won't really do harm to us.
2) If not, will the underlying connections (maybe from connection pool?) be finally returned back to system or connection pool? Say the system or connection pool will check abnormal connection states and retrieve back the resources after some long time?
The garbage collector will collect only managed code. This is why we have the IDisposable interface.
The underlying connection is not managed code, and therefor will not be closed by the garbage collector.
The connection pool will close the underlying connection after x time it's closed and not used. A "real" connection to the database that is tied to an open instance of IDbConnection will not be available for the connection pool to give out or to close.
Combine these two facts together and you'll soon understand that keeping an open connection on the class level will not only prevent it from being collected by the garbage collector as long you have an active reference to that class, but also prevent the connection pool to kill the underlying connection.
This leads to a number of problems already mentioned in the comments.
I understand you have a lot of classes connecting to the database like this (BTW, even back in the days of VB6 and ADO it was a bad practice) - so changing each class manually is not feasible.
However, you can create your own classes to add a layer between the application code and the ADO.Net code, and instead of mapping ADO directly to ADO.Net, map it to your own class.
So basically you'll have a Connection class that implements the IDbConnection interface and a Command class that implements the IDbCommand interface.
In your IDbCommand implementation you should open and close the actual connection when executing the command methods.
This way, you have a relatively small amount of work mapping the old code to the new code, and all the benefits of only using the connection when you actually need it.
Actually I am confuse about one thing.
I have .net application and using sql server 2008 for database.
Now, on my Method A i am filling datareader.
now, during while loop i am calling another method B by pass one property of result.
at that time i also open DB connection & close it.
same thing doing Calling another method C from method B.
at that time also open DB connection & close.
To fill final list of Method A. it is taking time.
so, my point is.To open DB connection & closing it. Is it time consuming process?
To open DB connection & closing it. it is time consuming process
Yes. If pooling is enabled and the connection is returned from the pool then opening and closing costs at least one round-trip, to reset the connection. If the connection is not pooled opening and closing is a full SSPI complete handshake. If SQL authentication is used and encryption is enabled, there is another complete SSL handshake to establish a secure channel before the SQL handshake. Even under ideal conditions, it takes 10s of ms, it can go up to whole seconds with some minimal network latency added.
A well written ASP.Net application needs one (pooled) connection per request, never more.
It is generally very bad practice to connect to a third part application (database, WebService or similar) in any kind of loop. Communication like this is always takes a relatively long time.
As the number of elements in the loop increases the application will become exponentially slower and slower.
A much better approach is to perform an operation for all the elements then pass the required data into your loop logic.
As with all things there are exceptions, loops where you have millions of entities to process and the connection is a small overhead may create circumstances where it's more efficient to process each entity atomically.
This question already has answers here:
Best Practice for WCF Service Proxy lifetime?
(4 answers)
Reuse of WCF service clients
(2 answers)
Closed 9 years ago.
I have a UI application in which I consume a WCF service like this
public MainWindow()
{
....
mServiceClient = new ServiceClient("EndPointTCP");
}
Should I create the client as a member of class and close the client along with exit of my application or Should I create a new client whenever its required in a method and close there itself.
It depends solely onwhat you want to achieve. There is no "best way to do it" since both ways are possible, good, and have different tradeoffs.
Holding the clientobject simply wastes resources. It also may leak context data between calls. You might have a bug that will cause mClient.Buy(100) and mClient.Sell(100) to work properly when used alone, but fail when used together mClient.Buy(100); mClient.Sell(100). Dropping and re-creating fresh instance each time could save you from that one bug, but obviously that's not a good argument for it.
Recreating the client each time a call is to be made has however the vague benefit of .. having a fresh client every time. If your app has a possibility to dynamically change the endpoint during the app's runtime, then automatically your client will be always using the newest addresses/logins/passwords/etc.
However, not recreating the client object at every time is simply faster. Mind that it's WCF layer, so the actual underlying connection can be any. Were it some protocol with heavy setup with some keyexchange, encryption, etc, you may find that creating a new client every time might create a new connection at every time and it will slow down eveyrthing, while keeping the instance will work blazingly fast, since connection might be kept open and reused. Often you try to keep the connection when you have to perform many and often calls to the service, like 24h/day twice/sec monitoring some remote value for breaching safe limits.
On yet the other hand, you might not want the connection to linger. Your remote service may have thousands of clients and limited resources, so you might want to close the connection ASAP so others may connect. Often you'd do it like that when the calls to the service are really rarely done, only once in a time, ie. when user clicks after returning from coffe break.
Please don't get me wrong: all above is just conjuring some vague "facts" from a void. I do not know your app, nor your service, nor your bindings (sans "endpoint TCP"). The most important factors are all on your side and they sit in the actual way how your app and that remote service work and interoperate. If you care about what you ask, you must first simply research the topic on your side. Best - simply try both ways and check if it works and how does it perform. The difference would be something like 2..6 lines of code, so that's, well, rather quick.
There are already some similar questions:
Reuse of WCF service clients
Reusing a WCF service client or creating one each time?
In my opinion it depends on your application type (scalability, performance requirements, ...) but usually I think that it's more safe to recreate the ServiceClient each time. In this way you don't need special code if there are connections problems between requests and with the latest version of WCF seems that there isn't a big performance impact.
See http://msdn.microsoft.com/en-us/library/aa738757.aspx.
Consider also that ServiceClient is not thread safe (at least reading MSDN).
There's a lot of non-detailed questions on this one, so here goes.
What is the best practice for connection handling in C# with SQL Server 2008? We have an assembly (which in our case is used by a WCF Service) that makes calls to an SQL Server. In general it seems like you need three objects to do this: The connection object, the command object, and the reader object.
The only reliable way we've been able to get the calls to work is to do the following:
Open the connection.
Create the Command in a using() { } block
Create the Reader to handle the response.
Dispose of the reader.
Implicitly dispose of the Command at the end of the using() block
Close the connection.
We ran into an unusual problem when running the same command multiple times iteratively, where it would complain that there was already a command or reader object attached to the connection that was still open. The only rock solid solution was to close and reopen the connection with every command we did, iterative or just sequential (different commands.)
So this is the question, since I come from a mysql_pconnect background on DB connection handling.
Is it going to significantly impact performance to be opening and closing a connection for each command?
If so for 1., what is the proper workaround, or code structure to handle serially repeating a command?
Is there any way to reuse a connection, command or reader at all?
If not for 3., does this really impact performance or memory usage significantly (As in, our users would notice.)
To answer point 1, if you look at the documentation for SqlConnection you'll see it explain about connection pooling. This means that the SQL Server provider has a collection of connections readily available and each SqlConnection created simply gets the next available connection. Therefore, to get the best performance, it is advisable to keep creating SqlConnection objects and using them for short operations and then disposing of them, thereby returning back to the connection pool.
For point 3, I believe you can re-use an SqlConnection if you do SqlCommand.ExecuteNonQuery(), but if you use an SqlDataReader you cannot re-use the connection - it is tied to the SqlDataReader and must be closed/disposed of once finished.
In addition to #PeterMonks answer:
The "expensive", unmanaged part of the SqlConnection is re-used by the provider (connection pooling) as long as you use the same connection string. So while there is a small overhead to creating a new managed wrapper each time, it isn't actually a 1:1 relationship with creating connections to the SQL server instance, so it isnt as expensive as you might think.
To serially repeat a command that returns a data reader, you must a) always execute the command on the same thread (commands are not thread safe) and b) Close() or Dispose() the DataReader instances before creating the next one. You can do that by putting the DataReaders in a using block as well.
Here is how you put the reader into a using block:
using (var dr = myCommand.ExecuteReader(...)) {
// Previous discussions have indicated that a close in here,
// while seemingly redundant, can possibly help with the error
// you are seeing.
dr.Close();
}
Another useful technique, as #DavidStratton mentions, is to enable MARS, but be aware that there is overhead associated with keeping resultsets open- you still want to close your readers as soon as you are done with them, because unclosed, undisposed readers do represent significant resource allocations on the server and the client.
I have an SQL server on a server at home (which is an Atom processor with 1GB ram), and i'm using it to store data for one or two of my applications. I was wondering if i should create a DataContext object when the program starts then hold onto it for the entire life of the app, or only create the connection when necessary. What happens if the application dies suddenly? does the connection get cleaned up?
Unless you're handing DataContext object an already open SqlConnection, DataContext will automatically close the database connection after the completion of a database operation anyway. So it won't keep the connection open. You can see this by looking at DataContext class in Reflector or you can read ASP.NET MVC Tip #34: Dispose of your DataContext(or Don't) blog post. So even if your DataContext object continues to live, there should not be any open database connection.
If you're handling the database connection outside of DataContext and keeping it open, then you really should not do this. Generally, you should create and use resources when and where you need them including DataContext object. There is no need to keep a database connection open without any demand for it, close it so that it gets released back into the pool to serve another database connection request. As I said, if you're letting DataContext handle the database connection, you don't need to do anything special as far as the database connection is concerned.
If your application crashes suddenly and terminates, you should be ok since everyhing will die including open database connections and the underlying connection pool associated with your application domain.
Bring up the data context when you need it and get rid of it when you're done.
Having one global datacontext means you have to pass it around to everything that needs it. (Every method you write that needs database access has an extra parameter in its signature).
Having a single global datacontext is also just going to become a pain if you ever decide to multi-thread one of your apps.
Have you looked at SQL connection pooling in .NET? Have a look at the article at http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.80%29.aspx. Connection pooling takes care of all the dirty work for you and automatically cleans up after itself if an error occurs in your program. It's pretty efficient at re-using connections so there is very little overhead in re-using the connections (creating the first connection when your program starts still has the same cost). It might be overkill for small applications but it's probably a good habit to get into for larger projects.