Typed DataSets are a type safe wrapper around a DataSet which mirrors your database structure. It was created to make sure that the code accessing the database is type safe and any changes in the database structure that changes tables, columns or column types will be caught at compilation time rather than runtime.

If you have a big typed dataset that contains a lot of tables, columns and relations it might be quite expensive to create it in terms of memory and time.

The main reason that creating a big typed dataset is expensive is due to the fact that all of the meta data that is contained within the typed data sets (tables, columns, relations) is created when you create a typed dataset even if eventually all you’ll use it for is to retrieve data from a single table.

I can speculate that the reason all of the typed dataset meta data is created during the instantiation of the typed dataset is due to the fact that it inherits from a generic DataSet and accessing the meta data (tables, columns) can also be done in a non type safe manner (i.e. access the Tables collection and/or Columns collection of a table).

If you are using a typed dataset (or dataset in general) you might be interested in the following tips:

  • If you have a big typed dataset, avoid  creating it too many times in the application. This is specifically painful for web applications where each request might create the dataset. You can use a generic DataSet instead, but this might lead to bugs due to database changes and the fact that you’ll only be able to find these bugs during runtime rather than compilation time (which basically misses the whole point of using a typed dataset in the first place).
  • DataSets (typed datasets included) inherits from the MarshalByValueComponent class. That class implements IDisposable which means DataSets will actually be garbage collected after finalization (you can read more about finalization and the finalizer thread here). To make sure datasets are collected more often and are not hagging around waiting for finalization make sure you call the “Dispose” method of the dataset (or typed dataset) or use the “Using” clause which will call “Dispose” for you at the end of the code block.
  • Don’t use DataSets at all :-) Consider using a different data access layer with a different approach such as the one used in the SubSonic project.

I guess it would be rather trivial creating a typed dataset that is lazy in nature which creates the meta data objects only when they are accessed for the first time. That would reduce the memory footprint of a large typed dataset but will make the computation used to create these objects a little less predictable. If you are up to it or already did a lazy typed dataset ping me through the contact form :-)

I’ve previously written about Internal .Net Framework Data Provider error 6 and how to obtain the hot fix to fix this issue.

It appears this hot fix never made it to .NET Framework 2.0 SP1 and there is a special fix (and KB article) to apply because the hotfix mentioned in the previous post will simply not work.

To get the hotfix for a .NET Framework 2.0 SP1 installation you’ll need to request a fix for KB948815 in the hot fix request web submission form.

In relation with my previous post about string.GetHashCode being used in AJAXControlToolkit’s ToolkitScriptManager class, I wanted to talk about object.GetHashCode in general, and string.GetHashCode specifically.

string.GetHashCode documentation states:

“The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language runtime to another. A reason why this might happen is to improve the performance of GetHashCode.”

The real conclusion from this paragraph is that you shouldn’t base your implementation on string.GetHashCode. But this is a bit too harsh since GetHashCode in general and string.GetHashCode specifically are being used throughout the runtime for internal things.

As long as you don’t share this hash code outside the boundry of the AppDomain its relatively safe to use.

The reason you cannot (or should I say should not) pass it across an AppDomain boundry is that the basic implemenetation of object.GetHashCode is to return an integer representing the reference id of the object in the .NET runtime. That reference is not guarenteed to be the same for the same object in a different appdomain/process/machine.

In the case of string.GetHashCode, where the implementation differ from the default one, you can pass it across AppDomains and even machines (though you shouldn’t count on that as well!) as long as they are in the same architecture, i.e., 32bit to 32bit and 64bit to 64bit.

All in all, the most recommend way of using x.GetHashCode is simply not using it at all. There are numerous implementations of hashing functions built into .NET (such as MD5, SHA1, SHA256, etc) which are more consistent but may be a bit more expensive computation wise.

For all your outward facing code I would recommend using one of the common and known hashing functions specifically if this is a case where the code on the other side needs to recompute the hash and compare it with the hash value being passed.

If you mix and match 32 bit machines/processes with 64 bit machines/processes in an ASP.NET load balanced environment and you are using the AJAXControlToolkit ToolkitScriptManager class you might end up with the following error:

Message: Assembly “AjaxControlToolkit, Version=1.0.10920.32880, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e” does not contain a script with hash code “9ea3f0e2″.
Stack trace: at AjaxControlToolkit.ToolkitScriptManager.DeserializeScriptEntries(String serializedScriptEntries, Boolean loaded)

at AjaxControlToolkit.ToolkitScriptManager.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The reason is that the request being sent to retrieve the combined javascripts of the control used in the page contains a hash code that is used internally. That hash code is being generated from the script’s name using the default string.GetHashCode function which returns different values for 32 bit and 64 bit processes.

If your 64 bit process creates the javascript include call which contains the 64 bit hash code and the request will eventually reach the 32 bit process/machine you will get this error since the hash value will not be found internally and vice versa.

There is an open issue about this in CodePlex since late January but as of the time of this post, the latest source version in CodePlex doesn’t have a fix for this.

If you are getting the error “Internal .Net Framework Data Provider error 6″ and you are using SQL Server 2005 with database mirroring know that its a bug in the SQL managed client code.

Check out KB article 944099 for more info.

At the time of writing this post the only solution for this problem is a private hot fix that you need to obtain from Microsoft.

The links around the web for the Hotfix Request Web Submission form seems to be broken. I’ve contacted Microsoft and got this replacement link.

Use this link to contact Microsoft, state that you require the hotfix for KB article 944099 and submit the form. You will be contacted shortly by a Microsoft representative that will give you the download details or request further information to better understand your needs.

I’ve just been asked through the “Ask” widget on the side of this blog on Yedda (my day job) this question:

Yedda – People. Sharing. Knowledge.Where is sos.dll for .net 3.5?

I installed Visual Studio 2008, but I don’t see sos.dll in the Microsoft.NET\Framework\v3.5 directory? What’s up with that?

Topics: , ,

Asked by dannyR on January 03, 2008

View the entire discussion on Yedda

To which I replied:

Yedda – People. Sharing. Knowledge.Where is sos.dll for .net 3.5?

There is a bit of confusion as to the .NET Framework versions as opposed to the CLR (Common Language Runtime) versions.

Up until .NET Framework 2.0, the CLR versions advanced side by side with the versions of the framework.

Starting from .NET Framework v3.0, the version of the CLR stated at 2.0 (there was no significant change in the CLR itself) and the framework’s version kept on going forward.

.NET Framework v3.5 actually runs on CLR 2.0 SP1.

This means that you can should be able to use the SOS.dll located at Microsoft.NET\Framework\v2.0.50727 with either Visual Studio (as I’ve explained on this post) or with WinDbg.

Dave Broman of Microsoft has written a post about the mapping of the versions of the .NET Framework to the version of the CLR. Do mind that as Dave states in his post, its the way he figures things up in his head and not the official documentation on this matter.

Topics: , ,

Answered by Eran on January 03, 2008

View the entire discussion on Yedda

I know its a bit confusing and I’m not really sure why Microsoft detached the versions of the Framework from the versions of CLR (well, I can understand some of the thoughts leading to this but I don’t think it was that good of a move) but Dave’s excellent post does put things in perspective and allows figuring out in what version of the CLR you are actually using.

I haven’t written in a while and I don’t like being an echo blog but this couldn’t pass right along.

ScottGu announced 2 days ago (yeah, I’m slow to catch that up, but its been a holiday here in Israel ;-) ) that they’ll release the full source code of the .NET framework library with Visual Studio 2008 so that everyone can browse it as well as be able to debug (which is always helpful).

In addition to that, it seems that VS 2008 will have integrated symbols server support which also includes downloading the debug symbols as well as source code directly from Microsoft.

Way to go Microsoft. This is exactly what I was missing for quite a long time!

Sometimes in ASP.NET when you are trying to access a certain page you might get the following error:

External component has thrown an exception

In some other situations in .NET you might get this error as well (not directly related to ASP.NET, but sometimes to Interoping code or COM code), but this is beyond the scope of this post.

In the cases that I’ve stumbled upon, the reason is usually related to on-the-fly compilations ASP.NET performs when first accessing a certain page on an application.

The main problem with this exception that it is less than informative :-) . The only way of actually figuring out what is wrong (if this is indeed a case related to compilation error like I’m talking about) is to dig deep using WinDbg.

Luckily, every compilation that runs inside ASP.NET uses an API that upon encountering an error will create an object in the heap called CompilerError.

To debug this issue perform the following steps:

  1. Attach WinDbg to the ASP.NET worker process (w3wp.exe in Windows 2003, aspnet_wp.exe in Windows XP/2000)
  2. Make sure you have CLR exceptions enabled (see this previous post about how to enable CLR exceptions in WinDbg).
  3. Try to access the page that is not working, it should throw an exception and WinDbg should break in.
  4. Run the following command:

    !dumpheap -type CompilerError

    This should produce a list of all CompilerError objects which should allow us to inspect them and see the exact compilation error.

  5. Now dump each of the objects using the following command:

    !dumpobject 0xXXXX

    Where 0xXXXX is the address of the objects listed in the list you got from the !dumpheap command.

  6. At that point you should see the CompilerError object itself and you can dump its errorMessageText member (it’s address is near its name) using !dumpobject which should show you the exact compilation error.

In my case, the problem was that in the web.config file under the <compilation> / <assemblies> element there was no reference to one of the AJAX.NET assemblies (System.Web.Extensions) which caused the page to fail during on-the-fly compilation.

Do remember that this exception sometimes has nothing to do with compilation. If you don’t have any object of type CompilerError or there are a few but they make no sense in regards to the page you are accessing it might be something else.

The ASP.NET Repeater control is a very useful patten that minimizes code and allows you to use templates to represent repetitive data.

All of you are probably familiar with it and use it quite often.

Yesterday I had a big fight with the repeater control, and since most of the Internet (actually search engines for that matter) is filled with lots of data about the Repeater control and how to use it, I couldn’t find the answer I was looking for.

Apparently it was staring me right in the face.

The problem was that I needed to display a list of words with a comma separator and they should have looked like this:

word a, word b, word c, word d

but what I got was this:

word a , word b , word c , word d

An additional and unwanted extra space before the comma.

That code that I used in the ASPX file was this:

<asp:Repeater>

<ItemTemplate>

<% #Eval(”Text”) %>

</ItemTemplate>

<SeparatorTemplate>, </SeparatorTemplate>

</asp:Repeater>

All seems well, right? there is no space before the comma in the separator template, but there was when the whole thing was rendered.

The fix was quite stupid (and is quite fragile):

<asp:Repeater>

<ItemTemplate>

<% #Eval(”Text”) %></ItemTemplate>

<SeparatorTemplate>, </SeparatorTemplate>

</asp:Repeater>

The extra enter which placed the </ItemTemplate> element in a new line was the cause of this problem. That new line was translated in this case into a single space which made everything look weird.

It seem that the Repeater control (and possibly other template based ASP.NET controls) are sensitive to the ASPX formatting. They are not trimming the edges of content that resides inside the template ASPX element, thus making them susceptible for formatting weirdness.

The worst problem of all is that when you use Visual Studio’s auto formating (Ctrl-E, Ctrl-D by default, if I’m not mistaken) it will ruin the layout and you might end up with a Repeater that has an extra space even if you didn’t want it.

I can understand why the edges were not trimmed, so that you can and should be able to enter white spaces as part of your template, but Visual Studio itself when formatting a document to be more clearly read will mess things up and that is the true problem.

While this is not a “real” advanced .NET debugging issue and I didn’t use any cool tools to figure it out it annoying nonetheless :-)

If you get the following error:

System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

Make sure that you are closing your connection. Specifically closing connections that you opened transactions from.

It seems the Connection Pool implemented in ADO.NET has two lists. One for connections that you did not open transaction from and the other for connections that a transaction was opened (and did not close, yet).

The two lists share the same amount of connections set in the “Max Pool Size” parameter passed in the connection string (the default is 100).

Be sure to use one of the following patterns and make sure to call connection.Close() when you are done with running your SQL statements, otherwise, it will take until the next run of the Finalizer thread to call Dispose on your connection object which will return it to the pool.

If your application is loaded it might take quite a while until the Finalizer thread runs and by then you will exhaust your connection pool and start getting mentioned above.

The two patterns used in this scenario are:

using (IDbConnection = new SqlConnection()) {

DoSomething();

}

The “using” statement is only good for C# and it will call Dispose (which in turn will call Close) on your connection object.

Another pattern which is similar and gives you more control is this:

IDbConnection = new SqlConnection();

try {

DoSomething();

}

finally {

connection.Close();

}

The finally block gives you better control and can also be combined with a “Catch” block that you can gracefully handle various errors such as “Unique Key Violation” (if you application logic needs this kind of treatment).

If you really want to know that you have exhausted your connection pool and you forgot to run PerfMon (see my previous post about PerfMon) you can take a memory dump using adplus (you can read a little bit about adplus here) and use WinDbg and the SOS extension to look at the Connection Pool object.

Search for “ConnectionPool” and you’ll get various objects, one of them will be “DbConnectionPoolGroup” which has a property named “_poolCount” which can tell you the count of connections used on your pool. This will give you a rough estimate as to what is the status of your connection pool.