Skip Ribbon Commands
Skip to main content

Blog

:

Quick Launch

Home
Blog of Ken McNamee, containing my thoughts, comments and questions.
April 20
Gunnar Optiks (aka Sunglasses for Heavy Computer Users)

Lately, my eyes have been feeling a lot of strain after hours and hours of developing everyday which has also led to headaches. I didn’t used to have this problem but I guess age is finally catching up to me. After doing some research I realized that this is a very common problem but there are some solutions (of varying success). Some people who suffer from chronic eye strain due to heavy computer use recommend taking frequent breaks away from the monitor. Others recommend tweaking the brightness, contrast and gamma of the computer’s video output until you find that magical setting that is easy on the eyes yet doesn’t destroy the quality of the image – not easy to do. After having tried both of those recommendations, the strain on my eyes did get a little better but only slightly so. Then I heard about Gunnar Optiks glasses.

It might seem a little strange to wear what are basically sunglasses while sitting at your computer but the concept is very similar to sunglasses that you wear while outdoors which protect your eyes from harsh light and ultra-violet radiation from the sun. The Gunnar glasses help protect your eyes from harsh indoor fluorescent lights and the light emitted by your computer monitor. I can’t honestly say that I understand exactly how they work but I can honestly say that they do work, almost completely eliminating the eye strain I used to feel.

Not everything is rosy with these glasses however. For one thing, the price is pretty steep. The particular model of glasses I purchased on Amazon.com was $120 which seemed a little crazy to me at the time. However, if they help keep my eyes healthy and allow me to sit for longer periods at the computer without needing to take a break then they will pay for themselves very quickly.

The other problem I have with the glasses is the yellow tinting which is not distracting at all but does slightly discolor what I’m looking at on screen. If I’m working on something which requires that I get the color precisely right then I need to pull the glasses down briefly. It’s not a huge problem for me but something to keep in mind if you’re a graphic designer for whom precise color is very important.

I should also say that I wear contact lenses and the glasses in no way interfere with them. In fact, one of Gunnar’s advertised benefits is that the curvature of the lenses and the frame causes the humidity around your eyes to rise slightly so they don’t get dried out as easily. I can’t attest to whether this is true but I’ve never had a problem with dry eyes.

So, the upshot of all this is that I would strongly recommend these glasses to anyone who uses a computer for 6+ hours per day and already has a problem with eye strain or suffers from light sensitivity. They did take me a couple of days before I felt comfortable using them on a regular basis but now I can’t imagine sitting at the computer without them.

http://www.gunnars.com/

January 31
Bypass Image Caching in Silverlight 2.0

Recently, I’ve been creating a simple Silverlight app to display a bunch of weather images because, living in Florida, it’s always good to know what kind weather might be coming your way. Basically, there are a number of public images I want to display such as national weather fronts, webcam images from the beach and visible/infrared satellite maps which are all publically accessible URLs. Silverlight has a handy Image control with a Source property so I figured it would be very easy to add a bunch of these to a Silverlight control and either manually or automatically update them.

However, one thing I quickly realized was that the images were not being updated even though my app was definitely requesting the latest image from the server. A brief debugging session revealed the problem: even though I was telling the Image controls to reload their Sources, no outbound URL request was ever being made after the first one. A little Googling led me to the discovery that Silverlight practices automatic image caching which is nice except that there appears to be no way to turn it off.

While image caching is probably the appropriate behavior under most circumstances, there are some situations such as mine and maybe some financial apps in which you want to be displaying the most up-to-date image from the requested URL. Microsoft should have provided a switch to turn caching off completely or maybe just on a per-request basis.

So this was an annoying setback but there is a pretty simple solution. It appears that Silverlight simply uses the URL of the image as the caching key so all you really need to do is change the URL slightly while still giving the web server the correct information about the image you want. The easiest way to do that is to append a querystring parameter that is never the same, such as a GUID or an integer counter. Really it could be anything but I find that appending a GUID is the simplest method and pretty much guaranteed to always be unique within this context.

In order to test this I created a small Silverlight app with 2 Buttons and an Image control. One button requests an image using the same URL all the time and therefore will always get the image from the cache after the initial request. The second button appends the GUID to the image’s URL and tricks Silverlight into thinking that it’s a request for a different image than what is already in its cache.

image

Here is the XAML and code-behind for the control:

   1: <UserControl x:Class="SLWxControl.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     Width="700" Height="520">
   5:     <Grid x:Name="LayoutRoot" Background="LightSlateGray">
   6:         <Grid.RowDefinitions>
   7:             <RowDefinition Height="50" />
   8:             <RowDefinition Height="*" />
   9:         </Grid.RowDefinitions>
  10:         <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
  11:             <Button Name="btnReload" Width="120" Height="30" Content="Reload" Grid.Row="0" 
  12:                     Click="btnReload_Click" />
  13:             <Button Name="btnReloadNoCache" Width="120" Height="30" Content="Reload (No Cache)" 
  14:                     Grid.Row="0" Click="btnReloadNoCache_Click" Margin="4" />
  15:         </StackPanel>
  16:         
  17:         <Image Name="imgBeach" Grid.Row="1"/>
  18:     </Grid>

19: </UserControl>

 

   1: public partial class Page : UserControl
   2: {
   3:     private const string IMAGE_URL = 
   4:         "http://sciencecentercam.fas.harvard.edu/axis-cgi/jpg/image.cgi?resolution=hugesize&camera=1&compression=50";
   5:  
   6:     public Page()
   7:     {
   8:         InitializeComponent();
   9:         LoadImage(true);
  10:     }
  11:  
  12:     private void LoadImage(bool allowCaching)
  13:     {
  14:         string imageUrl = (allowCaching) ? IMAGE_URL : string.Format("{0}&guid={1}", IMAGE_URL, Guid.NewGuid());
  15:         imgBeach.Source = new BitmapImage(new Uri(imageUrl, UriKind.RelativeOrAbsolute));
  16:     }
  17:  
  18:     private void btnReload_Click(object sender, RoutedEventArgs e)
  19:     {
  20:         LoadImage(true);
  21:     }
  22:  
  23:     private void btnReloadNoCache_Click(object sender, RoutedEventArgs e)
  24:     {
  25:         LoadImage(false);
  26:     }
  27: }

The only problem I can see with this solution is that Silverlight will continually cache these images so this might cause a dramatic memory leak in the app which could be very bad. I have yet to figure out how to manipulate the cache or whether it’s even possible to do so. If it is possible then the preferred solution might be to check for the existence of an image in the cache first and then delete it before trying to request an updated image from the server.

October 30
Windows 7 on an Asus EEE PC 901

A couple of weeks ago I got one of those tiny Asus EEE PCs which is in the new class of computers called netbooks. It’s pretty small and light but just large enough to be really useful as a laptop. Originally, it came loaded with Linux which I left on for about a day before I longed for some of my regular Windows apps. So I dug out the product key for an old Dell laptop that I no longer use and installed Windows XP Pro on the netbook. While very slightly slower than the Linux that was on there before, the performance of XP on this machine is perfectly acceptable for my uses which are browsing the net, watching videos and reading books in PDF format.

Not being a big fan of XP anymore, I did try putting Vista on the Asus but it just felt a little too sluggish for my taste. However, watching the Windows 7 keynote on Tuesday morning I was a little stunned to see Steven Sinofsky show a netbook running the new OS. Actually, I was stunned, then skeptical and then finally curious. So I got my hands on a copy of the PDC build of Windows 7, first noticing that it was actually several hundred megabytes smaller than Vista 32-bit with SP1 integrated.

Playing it safe, I began by installing Windows 7 into a virtual machine with only 1GB of RAM allocated just to become familiar with the OS and see how it performed within those memory constraints. My first impressions were that it didn’t look terribly different from Vista but also that it was a very snappy OS even with just 1GB of RAM. Having installed Vista in a similar environment, my unscientific opinion is that Windows 7 is at least as fast as Vista and perceptibly faster.

So, having been satisfied with Windows 7 in a virtual sandbox, I was now ready to install it on my netbook… at 10 o’clock at night. I tried to keep my expectations low because I wasn’t even sure I would get past the initial setup dialog. Happily, the install proceeded quickly through selecting the partition for installation and then copying/expanding the files. However, it soon got bogged down during the later stages of installing and configuring the OS, sometimes spending upwards of 10 to 20 minutes displaying nothing but a blank screen and an intermittent blink of the hard drive light. Trying to be patient, I just let it run and it eventually appeared to install and then rebooted. It was now 1am.

After the reboot, something strange began to happen. All I got was a black screen, no hard drive light and no response to keyboard or mouse input. Figuring I was probably sunk, I did a hard reset and got the same black screen. I tried another hard reset except this time I must not have pressed the power button for long enough because it just put the machine to sleep. I believe that sleep is only supported if the OS has working chipset and video drivers so I was a little puzzled. At the very least it showed that it actually did boot into Windows. So I pressed the power button again to wake it up and was relieved to see a login dialog.

After logging in, I got the usual “personalizing” and “configuring” first-use messages so the system wasn’t usable yet. After about another 10 or 15 minutes, I finally got a fully functional Windows 7 desktop. The thing that initially amazed me was that it had Aero running with transparency enabled and I hadn’t even loaded any drivers yet! And even with the maximum eye candy running it didn’t perform too badly. I really had no expectation that my little Asus was capable of running Aero because I only got Vista Basic when I had previously installed Vista. That said, even though the glass effects in Windows 7 looked really nice there definitely was some lag in performance so I left Aero running and just turned off transparency. That allowed me to still enjoy the benefits of video hardware acceleration without the overhead imposed by the glass effects. So the machine was now fully installed and it was just after 2am.

Unfortunately, it wasn’t all sunshine and light because there were some things that just didn’t want to work. Most of the Asus software and drivers wouldn’t install, throwing up a message that the OS wasn’t supported. However, the most important driver (wireless networking) did install just fine, as did the Bluetooth driver. The only things I’m really missing are the shortcut function keys that control the volume. Other than that, I haven’t found much to complain about. A couple of times IE has temporarily gotten into a non-responsive state but there have been no application crashes or incompatibilities and not a single blue screen thus far. I’ll try to install some more software on it later and see where application compatibility begins to break down. It looks like IIS and .NET are installed so I may even try to do some development on it. Curiously, the .NET Framework version is 3.5.1 as opposed to just 3.5.

So my initial skepticism that netbooks could run Windows 7 has quickly gone away. In fact, it appears that Asus is already planning to release a Windows 7 based netbook as early as next summer! As for my Windows 7 netbook, it seems to be just as usable as Windows XP Pro was and is much, much nicer to look at. I was just amazed and impressed that the correct Aero-compatible video drivers were installed by default. I’m definitely keeping Windows 7 on this machine permanently and now I can’t wait for the open Beta early next year!

System Specs

Model Asus EEE PC 901
CPU Intel 1.6GHz Atom
RAM 1GB
OS Windows 7 32-bit Build 6801
Install Size ~9GB on a 16GB SSD drive
Battery Life ~6 hours (about the same as with XP and Linux)

Screenshots

Windows 7 on an Asus EEE PC 901

Windows 7 on an Asus EEE PC 901

Windows 7 on an Asus EEE PC 901

Windows 7 on an Asus EEE PC 901

October 28
Azure Development Lesson #1: Installing and Running the Samples

I started going through the Azure SDK and samples last night and got tripped up on a few issues. Here are some of the steps to get started with the basics of Azure development:

1. To get started, you'll need Visual Studio 2008 with SP1 and make sure you also have SQL Server 2005 (or 2008) Express installed with the SQLEXPRESS instance name. The SDK samples require this.

2. Install the Azure SDK from http://www.microsoft.com/downloads/details.aspx?FamilyId=BB893FB0-AD04-4FE8-BB04-0C5E4278D3E9&displaylang=en.

3. Install the Azure Tools for Visual Studio from http://www.microsoft.com/downloads/details.aspx?FamilyId=63D0D248-1B08-4F7D-ABDE-62EB75CB1E69&displaylang=en. Not required to run the SDK samples but you will need to install it to run the hands on lab.

4. Read this page, http://msdn.microsoft.com/en-us/library/dd179419.aspx. The RunDevStore.cmd step is critical because if this fails then nothing else will work. There will be a yellow warning once it gets to the end but you can disregard this. Just make sure there are no red errors.

5. Download, build and run the hands on lab sample from this page, http://mbrownchicago.spaces.live.com/blog/cns!2221DC39E0C749A4!1040.entry?wa=wsignin1.0. It probably will build correctly but throw a runtime error saying that it could not find the Microsoft.ServiceHosting.ServiceRuntime assembly. For some reason this assembly is not installed in the SDK's bin folder but in a ref folder. You can either copy the assembly into the bin folder or add the ref folder into your machine's PATH environment variable.

6. Finally, it probably goes without saying, but run everything with administrative rights.

If all goes well then this is what you should see when you run the hands on lab, with the Development Fabric UI running in the background.

Clipboard07

In addition to the samples and hands on lab, you can also learn more about Azure development from online videos such as here, here and here.

October 04
app_offline.htm

Recently I came across a useful little feature of ASP.NET 2.0 that allows you to easily take a web site offline without writing any custom code, fiddling with app pools or cracking open IIS Manager. If you simply drop a file called app_offline.htm into the root of the web site then ASP.NET will immediately stop the web application and unload the app domain. Any subsequent HTTP requests to the web site will merely serve up whatever is in the app_offline.htm file.

Note that you can't have any server-side logic in app_offline.htm since it is merely static. However, it provides a nice, clean way to take the site down for maintenance or any other reason. I'm using it to deploy new versions of the web app I'm working on. I drop in app_offline.htm to take the site down, delete all the old files, stage up all the new files and then simply delete app_offline.htm to bring the site back to life again.

October 04
CoolCommands

Having really gotten used to the Ctrl-mouse wheel functionality in Word and Firefox to easily change the font size, I was a little disappointed to see that Visual Studio 2005 doesn't support it. When projecting Visual Studio on my laptop it's annoying having to go into Tool->Options->Fonts and Colors and manually change the font to a specific size, then do it again when you realize that the new size isn't quite big enough for everyone to see. Luckily I found CoolCommands which is a little group of utilities – one of which is Wheel Font Sizing, exactly what I need. Written by Gaston Milano, CoolCommands also includes a quick Demo Font option which really jacks up the font size for presentations in bigger rooms. Thanks Gaston!

January 29
XPath Tutorial
I don't use XPath nearly enough to remember all the syntax. So on those occasions when I need to use it I always refer to this online XPath Tutorial for a refresher.