Bill Robertson's Blog

May 2006 - Posts

Atlas UpdatePanel with GetWebResourceUrl

I noticed there are two overloads for GetWebResourceUrl, one that allows htmlEncoding and one that defaults to htmlEncode = false.  Of course the only public method is the one that sets htmlEncode = false.  So when I put out a web resource in an atlas update panel it renders the link as:

<script src=”WebResource.axd?d=[value]&t=[value]></script>

This is not valid Xml because the & remains unencoded.  However all of the runtimes resource emissions use the internal GetWebResourceUrl method that DOES the html encoding

<script src=”WebResource.axd?d=[value]&amp;t=[value]></script>

The only way I have found to get a web resource url through an update panel is to use "hack" code.

string url = [x].GetWebResourceUrl( ... ).Replace( "&t=", "&amp;t=" )

which is clearly not good.  When I don't use the replace logic on it, the xml is invalid so the xml DOM is empty, therefore the altas client script blanks out the Panel's UI.

I'm currently exploring other workarounds.  I think I could get the internal GetWebResourceUrl method called up through reflection, but I shouldn't have to.  I've also posted this question on the asp.net forums.

IDisposable on a Struct

The ReaderWriterLock is an excellent thread syncing object.  Instead of having a single lock() statement that control access, it will allow simultaneous reads, but retain blocking writes.  It becomes very useful through a singleton object where you have several reads, but very few writes.  I find the syntax a little cumbersome though.

try
{
 myLock.AcquireReaderLock( 1000 );
 DoLockedRead();
}
finally
{
 myLock.ReleaseReaderLock( 1000 );
}

Some time back I created a wrapper around the lock that simplifies the syntax slightly.  This greatly simplifies the locking syntax using my favorite C# syntax…the using statement.

using( new RWReader( myLock ) )
{
 DoLockedRead();
}

I created the wrapper class as a class.  By default all Types I create always start out as classes unless I have a reason to use a value type.  Mostly it is because I don’t want my object to be a value type and copy it from method to method and end up memcpy the entire stack from frame to frame, but there are times structs are useful.

Recently I used this wrapper in a situation where I was inside a tight loop.  I know when you “new” up an object it creates the object and places it on the managed heap, so it can be garbage collected later.  However, inside a tight loop it probably isn’t good to go wailing on the managed heap when a struct might work.

The question I am unsure of is since I am implementing IDisposable on the struct, is the struct going to be boxed anyway thus added extra overhead as the stack memory must be boxed and placed on the managed heap.  I know I should just use CLR profiler and see what is happening with allocations, but I have never used it, only read about it.

Any thoughts?

Telligent Koolaid

"Drank the Telligent Koolaid"  I heard this joke in passing my first week at Telligent, or at least I thought it was a joke. 

We have hired an Evangelist. Read into it what you want, but the Koolaid tastes fine...

Default case "default" on switch block

Several days ago I spent about an hour and a half tracking down some problem I had with a new codebase.  I added a new sort field to the Header of a table and couldn't figure out why the sort wasn't working.  After stepping through the UI code, then the DAL code, then various other layers I tracked it down to the Sort method on the Business Entity object.  Inside that method was code similar to

switch( columnSort )
{
 case "FirstName":
  return collection.Sort( ItemColumn.FirstName );
 case "LastName":
  return collection.Sort( ItemColumn.LastName );
}
return collection;

Which is all well and good except I was adding a sort on the RegisterDate, so the method was taking "RegisterDate", not finding any matches and returning the unaltered collection.  It really wasn't an error, but the behavior was problematic.

Always, always put a default case on your switch block.  Typically my default block will consist of an ArgumentOutOfRangeException being thrown.  This is just an always guideline, there are certainly cases where you want to just code a default: and be done with it.

Most switch statements, when they are coded, are coded with all the cases in mind.  What happens when another developer comes back behind and adds a "case" to your switch statement, but doesn't know the switch even exists?  An ArgumentOutOfRangeException would have been a great marker for a second developer to immediately find the code he needs to modify.

If you are using a enum and have a switch statement off it, that is another excellent time to have a default case blowing up.  You might have string formatting method that takes an enum to format an int, someone else might later add another format to the enum, but not know about all the lines of code that use it.  Sure, if you have excellent regression tests it *might* be caught, but the case would have to be checked, but more than likely you don't.  From experience, an exception being through in a NUnit test suite will fail...instantly, and take about 5 minutes to modify the code rather than spending an hour stepping into and across each layer of your app.

More Posts