Friday, June 15, 2007

Rounding

In the .NET Framework, the System.Math class has methods for Ceiling, Floor, Round, and Truncate. Round has an overload for specifying the number of decimal places to round to but it doesn't support other intervals, for example: rounding to the nearest five cents.

The mathematics involved for supporting other intervals is quite simple when you know it but getting there and verifying it can take a few moments. Here is the general solution to save time next time I need it, or if someone else is looking for the same thing:

decimal offset = 0.05M;        // interval we are rounding to (5 cents)
decimal value = 1.23M;         // value to be rounded
decimal temp = value / offset;
temp = MyRoundToInteger(temp); // toward zero or banker's rounding function
decimal result = temp * offset;

You can exchange MyRoundToInteger for any of the afore mentioned Math class methods or even one of your own custom rounding techniques, as long as it rounds to zero decimal places

 Thursday, June 14, 2007

Premature Analysation

I was thinking today as I was resolving a few Code Analysis violations that perhaps I should stop. I will assume you are familiar with the quote "Premature optimisation is the root of all evil" and if you're not, you should be.

I've often had the feeling that something wasn't quite right when I adjusted my code to satisfy the various CA performance warnings. Today I have investigated that feeling further:

Winner of Zurich Marathon 2007 CA1809: Avoid excessive locals - Triggers when you have more than 64 local variables in a method because the processor registers can no longer hold them all and some will be moved to and from the stack. If you have this many variables in a single method you have other problems to worry about.

CA1811: Avoid uncalled private code - Triggers when a private method exists that isn't called directly. This is great for finding and removing dead code but this is more about readability and not runtime performance.

CA1812: Avoid uninstantiated internal classes - Very similar to CA1811 but at the class level. Once again, good for removing dead code but not really performance related.

CA1807: Avoid unnecessary string creation - This is for people who still insist of using ToUpper or ToLower on strings before performing comparisons. Embrace the Unicode world and pass the StringComparison enumeration to String.Equals and String.Compare calls. This rule belongs in the Globalization set.

CA1813: Avoid unsealed attributes - This might be the first real performance rule so far but it does apply specifically to reflection on custom attributes. If your application makes heavy use of attributes, you may want to pay attention here. I think though that your personal philosophy on preferring extendable classes versus sealed classes may have more weight here.

CA1801: Review unused parameters - Once again, this is an excellent rule for locating dead code that may be misleading or unnecessarily complicated to maintain. I am beginning to wonder if the Microsoft.Performance CA category is a misnomer.

This covers the first third of the 18 rules on the performance warnings list. So far only one could potentially undermine the performance of your application given the right conditions and I'd run an actual test to time this before I started making big changes.

However, the rules shouldn't be ignored, perhaps they should just be considered from a point of view other than performance. Hopefully investigating the rest of the list, which I plan to do in future posts, will reveal valid rules for improving performance. I'm expecting at least CA1818 to come though for me there.

Strength In Numbers

Since Visual Studio 2005 has made the whole process much easier, I strong name every assembly I work on. It's one of the first things I do when I add a new project to a solution: Choose a name, set strict compilation warnings, enable Code Analysis, assign a strong name key.

I have used a few open source projects lately and have been disappointed that the binaries haven't always been strong name signed. This means I have to get the source instead, setup a new key and adjust their build script to use it before I can even add it as a reference to my own project.

Weight Lifting There are several benefits to using strong names:

  • Optional deployment to the GAC.
  • Satisfy Code Analysis rule CA2210.
  • Use of the InternalsVisibleTo attribute.
  • Reference from other strong named assemblies.

I don't think I've ever deployed any assemblies to the GAC, so only the last three are relevant for me but I'm sure GAC deployment is important to people writing COM interop code or add-ins for unmanaged applications or it will be important one day when their project gets reused in that context.

The counter-argument is that strong names are supposed to provide security and handing out the private key file with rest of the source would defeat the purpose. However, Mike Downen, program manager for security on the CLR team, says this:

They have no revocation capabilities and they don't expire. Nor do strong names inherently provide any way to securely map a public key to a particular publisher. Thus, strong names should be used very cautiously when making security decisions.

For these reasons I think it is a good idea to strong name all assemblies. Perhaps use a different strong name private key for each program. The owner(s) of an open source project could even retain a private key separate from the one distributed by the open source repository and use it for signing official binary releases.

 Tuesday, June 12, 2007

Code Camp Is In Tents

A tent on the beach I was privileged to attend Code Camp Oz 2007 in Wagga Wagga this year and I highly recommend it to anyone working with .NET. Unfortunately not everyone can find the time to drive twelve hours across the country for a weekend.

However, anyone living in South Australia will have an opportunity to attend the upcoming Code Camp SA, a free event sponsored by the University of South Australia, the Adelaide .NET Users Group, and the Australian Computer Society.

It will be held at the UniSA City East West campus for both days of the July 7th and 8th weekend. Specific details and registration can be found on the ACS web site for Saturday and Sunday. When available, the scheduled program will be published on the ADNUG news page.

If the content and quality of Code Camp Oz is anything to go by, this is an event that shouldn't be missed. See you there.

 Monday, June 11, 2007

Home Hardware

I write this as the Queen's Birthday long-weekend in Adelaide comes to a close. My fiancee has been busy redesigning the front yard and I have been busy with all things technical as I usually do.

On all three days of this weekend - Saturday, Sunday, and the public holiday Monday - my fiancee has been to the local Bunnings Warehouse home improvement store to purchase tools, plants, and pavers for the garden. They were open 9am to 5pm all three days.

Closed Hardware Store Today, the public holiday Monday, I discovered that it would be really helpful if I had a wireless USB adapter to ease the repair of a friend's PC from the comfort of my home office. Unfortunately, I live in South Australia, where we have legislation known as the Shop Trading Hours Act.

This Act, allows home improvement and furniture stores, among others, to be open on public holidays but it denies this same right to electronics and computer stores. This also has the absurd side-effect that Harvey Norman stores open for the sale of furniture and bedding but close access to the computers and communications section of the building.

Why is the consumer allowed to build a garden shed or install a new light fitting on a holy day or a public holiday but not permitted to install a new hard drive or fit surround sound speakers in their lounge? A March 2007 review of the Shop Trading Hours was heavily in favour of maintaining these ridiculous constraints despite the increasingly 24x7 nature of today's lifestyle.

Each business should have the option to open for trading if and when they choose. This decision should be based on the demand for their goods and services on certain days and times, the affordability of staff wages at weekend and holiday penalty rates, the personal beliefs of the owners, and anything else that may impact the profitability of the type of business in question.

Likewise, the devout consumer will prefer to spend Sundays and holidays at their place of worship or having quality time with their family while those without religious concerns or family commitments and wanting to get the most of their busy schedule can shop for items they need.

 Saturday, June 09, 2007

Three Strikes

I bought a LinkSys WAG54Gv2 ADSL wireless modem a couple of years ago. It had a good price and listed many features but I've suffered with unreliable WiFi since and eventually added a standalone access point to my home network.

The local broadband community has a lot of complaints about the LinkSys modem too and the original v1 wasn't any better. For a company advertised as "A Division of Cisco", I was hoping for much more and I wasn't the only one.

As a result I usually steer friends toward something like the D-Link DSL-G604T, a modem that I've installed many times with reliable results. Recently though, a close friend, finally moving from dial-up to broadband, purchased a LinkSys WAG54Gv3 against my advice. I guess the price, the Cisco brand association and the feature list were more convincing than my protests.

Last night I helped install the new modem and configure a Notebook, a Wii, and an iPaq (sounds like the beginning of a joke) to connect to it wirelessly. A fourth player, a wired HP desktop PC, was used to initially configure the modem and couldn't have been easier. WiFi however, as it turned out, actually was a joke.

On all three devices, IP addresses were not being issued by the modem if WEP encryption was enabled but WAP and also no-encryption were fine. The fact that I tried WEP first is entirely another blog post but can be summarised as such: better than no encryption, combined with MAC filter, LinkSys overheat with WAP, and minimal possible damage from an attack.

DHCP over WiFi has been a recurring issue in my experience and it is very disappointing. It is incredibly fundamental and there seems to be an amazing lack of thought put into getting this functionality right. The WAG54Gv3 is new to the market and doesn't have too much feedback yet, but so far it looks like it could be LinkSys' third strike.

I've said before that buying the more expensive product in the first place would probably solve all this messing around, but where should the line be drawn? An entry level Cisco 857 ADSL modem router will easily set you back AU$700, that's double the price of almost every other option.

DasBlog Mobile

Today I had the pleasure of visiting this web site with a Windows Mobile device. I was thoroughly pleased to discover that, without any configuration on my part, the blog rendered in Pocket Internet Explorer in a very clean, usable form.

I was even able to read the comments and submit my own. I must say though that the limited input capabilities of many PDAs really emphasise how annoying CAPTCHA can be.

Anti-spam mechanisms aside, the DasBlog developers have done an excellent job to provide yet another feature out-of-the-box that I was worried I would have to implement myself.

Thank you.

 Friday, June 08, 2007

Small Business, Big Problems

I've had the pleasure of chasing down some complications on a recent Small Business Server 2003 R1 deployment for a client. As is our preferred style for building new machines, we installed Windows then we ran Microsoft Update over and over, rebooting in between as necessary until every available critical and optional update had been installed.

We then proceeded to deploy our software's prerequisites to the server followed by the software itself, and lastly configure the server ready for deployment to the client's network. This last part was interesting... the SBS licensing GUI would crash when we attempted to start it. Some extensive Googling found this KB article suggesting to disable DEP for the offending program. Problem solved.

A little later the program for creating Active Directory Users was crashing exactly the same way. I couldn't find any KB articles for this program but I tried disabling DEP for the entire system and rebooted. Problem solved again. However, I wasn't happy that turning off DEP was right.

I spent an evening wandering through forums and blogs about SBS and eventually concluded that SBS SP1 was supposed to solve the problems. Of course, we had installed all the Microsoft Updates so that should already be fixed right? Sadly, no.

It turns out that because Service Pack 1 for SBS2003 apparently changes too much it doesn't get offered via Windows Update, you have to find it, download it, and install it manually. To make things worse, SP1 for SBS is supposed to be installed before SP2 for Windows Server 2003 but Microsoft Update had already installed that.

Several hours later we had uninstalled Windows Server SP2, installed the multi-file SBS SP1 update, reinstall Windows Server SP2, broken the .NET 2.0 framework, repaired that, broken SQL 2005 Reporting Services then reinstalled that, and finally reapplied SQL 2005 SP2.

Next time I think we'll have to remember to install SBS 2003 R2.

Heading Virtual For The Winter

Last time I looked into the options for migrating physical machines to Microsoft Virtual PC/Server I only found the Virtual Server Migration Toolkit. I downloaded all the appropriate components and began following the installation instructions. I quickly found myself overwhelmed by a solution too complex for moving one or two desktops to virtual machines.

With a notebook refresh on the horizon I decided I should look into my options again, hoping to virtualize my old system as a form of runnable backup. I discovered an excellent collection of blog posts from over a year ago conveniently listed here. The articles are spread out but do an excellent job to explain the common problems and how to solve them. I am summarising the process here mainly for my convenience but I'm sure it will be useful to others.

  • Install the Standard/Generic IDE Controller driver on the physical machine.
  • Copy an image of the physical drive into a VHD*.
  • Use Safe Mode/Recovery Console to disable drivers that halt the boot.
  • Replace System32\HAL.DLL with HALACPI.DLL from the Windows CD.
  • Install VM Additions, uninstall unnecessary drivers.

For full details on achieving these steps, refer back to the original articles and you should end with a functional Virtual PC of your physical machine. Even better, your physical machine is untouched and still usable.

* The original articles suggest using Virtual PC's linked physical disk feature to mount the actual hard drive and then convert it to a VHD. Unfortunately, Virtual PC 2007 does not include this feature anymore, however I found this MakeVM software which sounds promising.

Of course, there is also the VMWare range of virtualization products which apparently have much better P2V solutions.

 Wednesday, June 06, 2007

ReSharper And Other Trivia

As Jim has recently explained, ReSharper 3.0 is now available in beta and for the first time supports VB.NET. As the majority of the code I work with each day is VB, I have, also for the first time, installed ReSharper. I am enjoying the experience so far and it works well across both VB and C# projects in the same solution.

However, as I've mentioned before, I use C# projects to test VB production code and ReSharper was failing to consider InternalsVisibleTo attributes and incorrectly marking code in my unit tests as erroneous. Thankfully Visual Studio still built and executed the code fine. Also very impressive was how quickly the guys at Jetbrains had solved the bug once I had emailed them. Try the nightly builds here for the latest version.

As a side note, if you're working with the InternalsVisibleTo attribute, you may find fellow Australian developer David Kean's generator very useful for extracting the rather long assembly PublicKey.

Now, if I can just convince ReSharper to give back my F12 key.

 Tuesday, June 05, 2007

SQL Server 2008

It's hard to keep up. Microsoft have recently released the June CTP for SQL Server 2008. You may need to sign in with your Windows Live ID to follow that link and you definitely need to apply for the SQL CTP program if you want to download it. I guess it makes sense for us to start seeing SQL 2008 now as it probably coincides with the Visual Studio 2008 RTM later this year.