I Didn’t Expect These Features

Monday, October 25, 2004

What do MARS and the new Edit and Continue features have in common?

  • Both were technically difficult to implement
  • I never expected either to show up.

Whenever discussions cropped up about these features the pushback always seemed to indicate both required major disruptions to the lowest level code you can imagine, and possibly changing the gravitational constant. Now these features are here in beta.

Edit and continue (E&C) allows a developer to edit code in a running application and continue running the updated application without having to stop, compile, and launch the debugger again. It’s amazing the range of responses this feature generates. Jonathon Goodyear proclaimed it would be a colossal mistake for Microsoft to not ship this feature in 2005. Sam Gentile (who is a C# MVP, just in case he didn’t tell you), feels E&C will ruin software development.

In the end these discussions always collapse into some sort of three way language war between people who use semicolons, people who don’t use semicolons, and people who use Smalltalk. It’s odd how that happens. I wonder what happens inside the meeting rooms around Redmond when this feature came up for discussion?

I don’t see myself ever using E&C, except maybe once every two years when some weird bug crops up in a windows service with a long setup time. Given it has taken 4 or more years to work this hot potato into the runtime, I’m sure I would have picked other features I could use in day to day work and never miss E&C.

At least with E&C you can take it or leave it. MARS, on the other hand, seems to be sneaking in with an impact on anyone using the native .NET SQL Server client.

Multiple Active Result Sets (MARS) lets a client have more than one pending request on a given connection. What does this mean in code? Consider the following snippet:

SqlConnection connection = new SqlConnection("[connection string]");
connection.Open();
SqlCommand command = new SqlCommand("[query 1]", connection);
SqlDataReader reader = command.ExecuteReader();
SqlCommand command2 = new SqlCommand("[query 2]", connection);
SqlDataReader reader2 = command2.ExecuteReader();

I just ran this with the October CTP of Whidbey and SQL Server. The application runs without error. In .NET 1.1, however, we would see an exception:

Unhandled Exception: System.InvalidOperationException: There is already an open
DataReader associated with this Connection which must be closed first.

The Technet document introducing MARS gives explanations and use cases for where this behavior is useful, and it also mentions: “In conclusion, we can say that MARS is all about getting rid of "Connection Busy", a significant improvement to the programming model.”. It does sound attractive on the surface, but…

You can ask anyone in the ASP.NET or ADO.NET newsgroups (like Bill, for instance), and they can tell you the aforementioned exception shows up time and time again in questions. The exception is usually the first clue a new developer has that they are not closing database connections. Oh well, you say, they will just have to learn the hard way, what impact is in it for me?

For starters, make sure to read the sections on “Performance and Cost Considerations” and “MARS Deadlocks” as food for thought. Even more interesting is the MARS FAQ on Angel Saenz-Badillos blog. Suddenly, creating a SqlCommand isn’t going to be quick and relatively free (and the OleDb provider has all sorts of caveats to watch for). MARS is on by default, and there really is no way to disable the feature to recover the cost or avoid the worst case scenarios for the feature.

ADO.NET seems to be replanting new pitfalls over the old ones we left behind in ADO. Surely, there must be some driving reason for this complexity in ADO.NET.

Could it be something required to build ObjectSpaces?


Comments
Bill Monday, November 15, 2004
It's too bad that they didn't decide to implement SqlResultSets - that would be a guaranteed 100 posts a month I could answer becuase, you KNOW how that would be misused. Think about it - ADO.NET's been out for like 3 years now and a week doesn't go by where Dynamic Sql and an Irish last name doesn't cause someone a problem. How many connections aren't closed? How many Try Catch blocks eat exceptions without closing them and the issue is totally hidden from the programmer? If these bad habits are still out there, well, MARS is going to 'interesting' to say the least. I'm all for it because, well, it's cool, but you can imagine how that's going to work. "I have a global connection for my data access layer and I never close it - not even when the program ends. I have a Recursive function with no exit condition and at each pass, I fire a new command. Now, something's wrong because nothing works, but I used Lock() around the connection so I know it's not my code. Is this a bug do I need to put a Lock around my ConnectionString too?"
<br>
<br>I'm just waiting to read something like this.
<br>
<br>One really cool thing I noticed though is that the new providers are much more resillient. You can have the Connection Pool filled up, pull the network cable and with Sql Server, when you try to open a new connection (assuming the cable got plugged back in), you'll only get one failure and then you'll be good to go - instead of now where you have to clean out the pool. The ORacle provider doesn't even fail once.
Ed Wednesday, August 10, 2005
This article http://www.developer.com/db/article.php/3440161 says you can disable MARS on your connection by including MultipleActiveResultSets=False in your connection string - useful if you are developing for SQL Server 2000 and 2005 back ends.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!