June 2004 - Posts

PINVOKE Reference

“...this site is a repository where you can find, edit, and add PInvoke signatures, user-defined types, and any other information that helps us leverage each other's efforts.“

Great site, trying to simplify use of API from managed languages. Should be in your favorites.

Identity vs Equivalence

Recent question triggered me to write this one.

When should we use == operator and when Object.Equals?
What if we need both Reference Identity and Object Instance Data Equivalence checks?

Those are usually very confusing questions. We have variety of methods to check reference equivalence and object identity in CLR with different semantics between Value and Reference types. If it is not enough, there are some historical problems with GetHashCode. Some of them you mentioned in your post. Worst, defined as Int32, hash code can not uniquely address more than 2^32 different objects. Ian Griffith just has excellent post here about it.
To make long story short, I will try to summarize identity/equivalence options we have in CLR:

Static Object.Equals - test for object equivalence.
Static Object.ReferenceEquals - test for object identity.
Operator == - defaults to identity test.
Object..GetHashCode – test for possibility of equivalence.
You can override Equals in derived type, but you will have to override GetHashCode also.

Best practices suggest overriding set of equivalence operators if you implement System.IComparable (see here). One reason for this is use of those operators in IList sorting internal implementation.

Some more information can be found in at dr GUI or this older discussion.

 

Choose right class for XML processing

How are you processing your XML in .NET?

Having all this reach API for XML processing, selection of the right classes is the key to building well performing, reliable code. Basically you have 3 choices:
1. Using derivatives of XMLReader/XMLWriter
     XmlTextReader xr = new XmlTextReader(new StringReader(xmlData));
     xr.Read();

2. Using XMLDocument (proved, MSXML veteran object)
    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(xmlData);
    XmlNodeList xnl = xdoc.SelectNodes("/Clients");

3. Using optimized, lightweight  XPathDocument (from System.Xml.XPath namespace) in conjunction with XPathNavigator
    XPathDocument xpdoc = new XPathDocument(new StringReader(xmlData));
    XPathNavigator xpn = xpdoc.CreateNavigator();
    XPathException xpe = xpn.Compile("/Clients");
    XPathNodeIterator xpni = xpn.Select(xpe);

Here are mine recommendations:
Use XMLReader/XMLWriter in performance oriented scenarios. Validation could be performed with XMLValidatingReader. You will pay development cost for speed.

Use XPathDocument for everything else!
Reasons:
1. In .NET 2.0 it becomes Read/Write.
2. XPathDocument optimized for XSLT and XPath processing, has less footprint, resulting in much better performance relative to XmlDocument. In some cases it will perform 10 times faster, and becomes even faster in Whidbey.
3. In .NET 2.0 can be used with XQueries.

 

Close current browser window

Another couple of common questions:

1. How can we make URL open in window with specific parameters (no toolbar for example)?

2. How can we close current window, without getting annoying alert: "The Web page you are viewing is trying to close the window"?

Basically it is the same question. We can build auxiliary HTML page that uses window.open() with requested parameters to open real URL as needed, and than closes itself. And just to keep browser happy, let him think that script, which asking to close window belongs to its opener. Here is your loader.htm:

<script>
window.open("RealURL.htm", null, "height=200,width=400,status=yes,toolbar=no,menubar=no,location=no");
window.opener = window;
window.close();
</script>

Difference between IMG and INPUT type=&quot;image&quot; DHTML elements

Just bumped again into <IMG …> against <INPUT type="image" …> differences question.

So here we go:

<INPUT type="image" …> creates DHTML control that in addition to all his events, when clicked, causes the form to be immediately submitted (just like <INPUT type="submit" …>). One confusing thing is that this control will receive "onclick" event on every enter user presses.

Conclusion: if you want pure client side processing, <IMG …> element is your natural choice

Solving client resources caching problem

Let's get back to the old client caching problem.

Consider the following scenario:
We have a web based application that contains static client resources (*.js, *.css, *.htc etc). We would like to exploit downstream cache, and be absolutely sure that the client receives up to date file version. Possible solutions are:
1. Play around with cache expiration header. Yuri had just posted the right way to do it. In case that the client's request had reached the server, the resource expiration date will be checked, and the updated resource or 304 (not changed) will be served. The main disadvantage of this method is a need for a client to make a roundtrip on each access to the resource. Even if we completely control all clients and make them ask for a new version of file on every visit (Settings of IE), we will still have to trust that all proxies between our client and IIS are playing nice and are not just checking against their own local cache. Even if we did manage to ensure all this, we will still get roundtrip on every visit to everything! Having not-so-wide connection, this can result in flickering and unnecessary server load.
2. Change resource URL with every update. Advantage is clear. It is absolutely bullet proof. You can use the most aggressive caching mechanism and still be sure resource is OK. Browser will have to go the whole way because the item with a new URL is not found anywhere. Unfortunately, disadvantage is also clear: It's a hell to support such a deployment scenario.
3. Whidbey client resource caching approach.
4. Any other ideas?


Whidbey is not here yet for a while, and we have variety of ASP.Net systems out there in production. What can we do today (that is better than instruct our clients to clear browser cache each time the problem occurs)?
We would like to change URL but don't want to deploy changes differently. Let's steal some Whidbey ideas. We will construct some mechanism that automatically modifies resource URL on each update. On the server side we'll use custom HTTP handler to map modified URL to real file.


Let's start with URL creation. It will be constructed as <original_file_name>_<version>_<content_type>_InfraScriptCache.js. First of all we will use version indicator from Web.config file to automatically modify URL. Pay attention to resource extension. It appears that majority of browsers don't trust unknown file extensions, and if the browser doesn't trust something, it will travel to server to check and to be on the safe side. To prevent it we let the browser treat all resources as js files and incorporate real content type into resource URL.  Extending URL with "_InfraScriptCache.js" is our way to let custom handler know it should process this request. We don't want occasional js files receive special treatment.
Now let's look at HTTP handler. It is really simple. The handler has to do just a couple of things:
1. Check "If-Modified-Since" header. If it exists in request, browser has the right version and is checking for updates. There is no change in version number, no need to proceed, just to serve 304 to client.
2. If "If-Modified-Since" is not here, browser is looking for updated/new file for the first time. Now we read the file, optionally in-memory cache it, set expiration date to a year from now (some browsers will disregard longer expiration period), and serve file.
Having both ends, all we have to do is setup Http handler on IIS (one time installation), and update version indicator in Web.config on each resource update.

Article with the whole source code is here for now. I'll try to upload it tomorrow in more readable form.

MS-SQL Best Practices Analyzer

For anyone who missed Kimberley's post – MS-SQL Best Practices Analyzer is a simple and very handy tool. If you pay attention to your DB as much as you do to your code (using FXCop or similar tools), check it out!

Mission Statement

Hi All!

So it's a historical event. It took me too long, but finally I am starting my first blog!

A lot of thanks to Donny for hosting me.

I intent to share here some thoughts, considerations and doubts about software architecture, .NET developing, extreme sport and Extreme Programming.

I hope somebody will find here useful bits.

So welcome, and see you soon!