August, 2004

Posts
  • Eric Gunnerson's Compendium

    Arrays inside of structures

    • 9 Comments

    Sometimes when doing interop, you want to have an array embedded inside of a struct. For example, something like:

    struct data
    {
        int header;
        int values[10];
    }

    that you either used in a call to interop, or with unsafe code to deal with an existing format - something like a network packet or a disk record.

    You can do this in current versions of C#, but it's ugly. The most obvious way is:

    struct Data
    {
        int header;
        int value0;
        int value1;
        int value2;
        int value3;
        int value4;
        int value5;
        int value6;
        int value7;
        int value8;
        int value9;
    }

    But that's a bit ungainly, though, you *can* take the address of value0 and then use pointer arithmetic to access the various "array elements". There's a somewhat shorter version:

    [StructLayout(LayoutKind.Sequential, Size=44)]
    struct data
    {
        int header;
        int values;
    }

    Setting the size to be 44. If you want to have more than one such array or have fields after the first one, you'll need to use LayoutKind.Explicit and put a FieldOffset attribute on every field.

    In either case, you access the "array" by getting a pointer to the values field, and using pointer arithmetic.

    To make this a little cleaner and less error-prone, in C# 2.0 we've added a fixed array syntax, allowing you to write:

    struct data
    {
        int header;
        fixed int values[10];
    }

    and getting the exact same behavior. You can then treat values as if it's a "c-style" array, using indexing, etc.

    Because the underlying implementation is still using pointers and there's the possibility of going outside the allocated space, code generated using this feature requires using "unsafe", and therefore requires elevated privilege to execute.

  • Eric Gunnerson's Compendium

    List<Employee> or EmployeeList?

    • 35 Comments

    In current versions of C#, to get a strongly-typed collection, you need to define a separate type for that collection. So if you want to expose a collection of employees, you created an EmployeeCollection class.

    With generics, it's now possible to just use List<Employee>, and it's also possible to write a pretty simple version of Employee collection as well:

    class EmployeeCollection: List<Employee> {}

    So, which one is preferred?

    My advice is to prefer List<Employee>, as anybody who looks at such a definition will already know what operations are present on it, while it's not clear what operations an EmployeeCollection might provide.

    I would switch to EmployeeCollection when I want to add behavior beyond what List<T> provides (I obviously *have to* switch if I want to add behavior).

    This also has the added benefit of not cluttering up the program with types that really don't need to be there.

  • Eric Gunnerson's Compendium

    Miss manners will help you now...

    • 47 Comments
    Etiquette Hell
  • Eric Gunnerson's Compendium

    Nested Using Statements

    • 19 Comments

    I got a comment on the language feature post, asking about an easier way to write:

      using (StreamWriter w1 = File.CreateText("W1"))
      {
          using (StreamWriter w2 = File.CreateText("W2"))
          {
              // code here
          }
       }

    You can do this by writing:

      using (StreamWriter w1 = File.CreateText("W1"))
      using (StreamWriter w2 = File.CreateText("W2"))
      {
          // code here
      }

  • Eric Gunnerson's Compendium

    Be a language designer...

    • 55 Comments

    I started writing a normal blog post - well, as normal as any blog post of mine ever is - and then I decided to let you do the hard work. So here's the situation.

    You're part of the C# language design team thinking about the next version of C# (ie the version after VS 2005). You get the following email:

    When I'm writing code, I often come across a situation where my code throws an exception because another component called with a null parameter. I'd like a way to prevent that from happening.

    What are the pros and cons of such a feature? What are the ramifications of adding it to the language? What would have to change? What is your recommendation? Exactly what would such a feature look like?

  • Eric Gunnerson's Compendium

    New Challenges

    • 29 Comments

    From C# Builder to C# User...

    Dateline: Redmond, Building 41

     

    Eric Gunnerson called me early this morning, asking me to come by to talk with him. When pressed, he would only reveal that he had news to impart that would “Rock the very foundations of society... Or be a good filler piece. Definitely one of those”.

     

    So, I grabbed my notebook and headed over, wondering what the morning would yield. Eric is the noted author of “Bad Roomba!”, “Hangin’ with Generics”, and the critically acclaimed “Tantric Snacking”, so I expected something big.

     

    Me: So what’s this important news?

    Eric: Well, the news is that I’ve decided to leave the C# team to join the Windows Movie Maker team as a developer.

     

    Me: What does that mean?

    Eric: Developer? It’s someone who writes software. Are you new here?

     

    Me: No, what does your leaving mean?

    Eric: Well, first of all, it means that instead of showing up at building 41 every morning, I’m going to be showing up at building 50 instead. At least for the first month or so – I expect that after that, I’ll occaisionally find myself in the building 41 lobby, feeling very confused.

     

    Second, it means that instead of working to help further the C# language, I’ll be using the C# language to help build a really cool app on top of Avalon and Longhorn.

     

    Third, it means that some of the things you currently see me doing you’ll soon see other C# team members doing.

     

    Oh, and it probably means that those of you who meet directly with the C# team will be subjected to fewer bad puns, though I obviously can’t make any promises.

     

    Me: Why are you leaving?

    Eric: To put it simply, it was time to move on to new opportunities, explore new vistas, climb every mountain, ford every stream... Where was I? Oh, that’s right...

     

    Every year I spend some time looking at what I’m doing (both inside and outside of work), and evaluate what I want to do for the next year. This year, when I did that, I realized something.

     

    I wasn’t enjoying life enough. I was going to say, “I wasn’t having enough fun”, but that sounds too frivolous. I was doing too many things that I wasn’t excited about doing. And I wasn’t spending enough time with my family, and even when I was with them, I wasn’t engaged.

     

    So, I stepped back and looked at what was wrong, and what I realized was that I had lost passion for my job. I’ve always felt that you spend too much time at work to spend it doing something you don’t at least like, and preferably love.

     

    My attitude towards my job had bled over to other parts of my life. I hadn’t coded for fun in a couple of months, nor had I launched any rockets, played with microcontrollers, gotten any house projects done, or experimented much in the kitchen.

     

    So, what did I want to be when I grew up? That was the question.

     

    I considered a number of different options. Could I be a full-time author? What about a trainer? What about getting into the construction business? Or going back to the QA side at Microsoft?

     

    I mulled these over for a few days, but my thoughts always came back to code. In the years before Microsoft, I wrote a lot of code, and I miss that feeling of immersion when you realize that 4 hours have passed without you really noticing. It’s a state of being as much as a state of thinking.  There’s an interesting parallel to long-distance cycling, as I can reach a similar state there. Or, strangely, finish carpentry.

     

    In the Microsoft world, “code” == “dev”, so started to explore dev positions.

     

    Me: (starts) huh? Sorry, I think I dozed off for a second there. Umm... so why the Movie Maker team?

    Eric: I looked at a number of different openings. Unfortunately, the C# team and most of Visual Studio is still written in unmanaged code, so the positions there tend to be COM and C++ oriented. I’ve done a fair bit of C++, but if you’re going to move, why not find something you really want to do? No offense to COM programmers, but “ick”.

     

    I also looked at the teams that write frameworks, but decided it would be more interesting to work on an end-user application.

     

    I did several informational interviews, which are informal meetings between a manager and somebody who is interested in that team. It’s how both parties figure out whether it makes sense to spend the time on an interview loop. Why is it a “loop”, anyway? It’s not like you talk to the same person more than once...

     

    The Movie Maker team is doing some really cool stuff, and I’ve had a soft spot for graphics since doing so meant you wrote your own graphics library for a ReGIS terminal and then shot movies one frame at a time. By yourself. In a dark terminal room. On Saturday night. Plus, it’s C# code, working with all the cool Avalon stuff, and it’s a small team. Oh, and I used to work with one of the devs on the team, way back in my VC++ days.

     

    I’m really excited about the team and where they’re (we’re) going.

     

    Me: Coming at this juncture, how do you think your departure affects the C# team’s chances of winning the pennant?

     Eric: Well, it obviously makes it harder for them to contend for the Division Championships, but I believe in this team, and I’m confident that they’ll find a way to continue their winning ways. I don’t think it’s going too far to say that “one person does not make a team”.

     

    Me: Will you still be involved in the community? Will customers still see you at conferences?

    Eric: I’ll still be writing my blog, though over time I expect it to morph from a blog that has a small amount of useful content about C# language design to one that has a small amount of useful content about using the C# language and writing for Avalon and Longhorn. I’m certainly going to continue providing valuable information, such as useful gift giving tips (link).

     

    For conferences and other events, I don’t really know the answer to that. Perhaps. I hope so.

     

    Me: When will you update your more-than-a-little-out-of-date book on the C# language?

    Eric: You mean my C# book from Apress, still available for the ridiculously low price of $34.95? No comment.

     

    Me: Tell me a funny C# story

    Eric: Okay. Two stories.

     

    The first one is a language design story, and I’m not really sure I can do it justice, but I’ll try. When we were working on the numeric types, the question arose around naming the signed numeric types. What would name the signed and unsigned byte types? We had int/uint, long/ulong, etc. We were discussing sbyte, and not terribly happy about it, when I pointed out that we already had precedence for doing “s byte”, with the “s hort” type. Then Scott suggested we abandon the current system for a different one, using “short”, “tall”, “grande”, and “venti”.

     

    Things deteriorated rapidly after that.

     

    Second story. Way back when the compiler was first coming online, I got one of the early drops, typed in “Hello world” (or some suitable variant), and went to compile it, but there was something wrong with the compiler, because I just got the command prompt back.

     

    I went and asked Peter Golde for help, and he came into my office and said, “did you do a directory?”. And there is was, Hello.exe, just sitting there. I’d never run into a compiler that ran so fast that you couldn’t tell that it had actually done anything.

     

    Me: What exactly are you going to be doing in your new team?

    Eric: Initially, I’ll be working on the small “v” of “Movie”, but I hope to move up to the “i” after a few months, and perhaps, if things work out, someday I'll get to work on one of the Ms...

     

    Movie maker is a fairly small team, so I’ll be working on different things – UI, transitions between clips, and likely writing a few wrappers around some unmanaged code.

     

    Me: When are you leaving?

    Eric: Over the next few weeks, I’ll be transitioning and vacationing. My last day in the C# team is 9/3, and my first full day in the Movie Maker team is 9/13.

  • Eric Gunnerson's Compendium

    Good subjects for IR photography?

    • 12 Comments

    I recently bought an accessory adapter and a Hoya R72 filter for my Canon G3, so that I could do some infrared photography. This is "near IR" photography, the kind where things look weird

    not thermal infrared, where you can see how hot things are:

    The filter cuts down the amount of light by a pretty huge amount - I went from a 400th of a second down to around a 4th of a second on an outdoor scene.

    The results were as I expected (weird and very red), but I'm looking for some advice on subjects.

  • Eric Gunnerson's Compendium

    Any COM interop experts out there?

    • 10 Comments

    I've been spending some time trying to get Windows Media Player to work in a remoted mode from C#. There's a C++ example in the WMP9 SDK named WMPML that does it, but it uses some special interfaces.

    To get it to work, I need to register an IWMPRemoteMediaServices object with the WMP player, but despite setting it through SetSite(), my IServiceObject implementation is never called to return the type.

    Anybody with some experience on the internals of AxHost and how this stuff works?

  • Eric Gunnerson's Compendium

    Conditional Methods

    • 16 Comments

    I saw an internal post today about somebody who wanted to get rid of their #if DEBUG statements in their code, because they were ugly. That made me realize that there's a feature that not everybody knows about, known as conditional methods.

    Consider the following code:

    using System;
    using System.Diagnostics;

    class Program {
        static void Main(string[] args) {
            #if DEBUG
            DebugMethod1();
            #endif

            DebugMethod2();
            Console.ReadKey();
        }
        static void DebugMethod1() {
            Console.WriteLine("Debug1");
        }

        [Conditional("DEBUG")]
        static void DebugMethod2() {
            Console.WriteLine("Debug2");
        }
    }

    In my call to DebugMethod1(), I've used the traditional #if approach to only compile the call if the DEBUG symbol is defined. But in the call to DebugMethod2(), I've used a conditional method that has the same effect - if the DEBUG symbol is not defined, it's as if the call isn't there. That includes any side effects from parameter evaluation - they don't happen.

    Note that the docs on the ConditionalAttribute class are a bit misleading.

  • Eric Gunnerson's Compendium

    "It's only a model"

    • 18 Comments

    I mentioned that I bought my wife a trebuchet. Here's a picture of it.

    And where does one go to buy a trebuchet?

    Well, duh.

    http://www.trebuchet.com

    Kim's is the tabletop version.

    Oh, and if you don't know what “It's only a model” refers to, I pity you...

  • Eric Gunnerson's Compendium

    1.1 SP1, 1.0 SP3 released

    • 23 Comments

    A few new service packs are now available.

    .NET Framework 1.1 SP1 for WS03

    http://www.microsoft.com/downloads/details.aspx?FamilyId=AE7EDEF7-2CB7-4864-8623-A1038563DF23

    .NET Framework 1.1 SP1

    http://www.microsoft.com/downloads/details.aspx?FamilyId=A8F5654F-088E-40B2-BBDB-A83353618B38

    .NET Framework 1.0 SP3

    http://www.microsoft.com/downloads/details.aspx?FamilyId=6978D761-4A92-4106-A9BC-83E78D4ABC5B

  • Eric Gunnerson's Compendium

    Hydrogen from Sunlight

    • 21 Comments

    John Read wrote in this ABlog post (I hate group blogs):

    The Aussies have done it. And not a moment too soon! Using special titanium oxide ceramics, they can now use sunlight to split water, and produce hydrogen fuel for unlimited energy. The device rivals still-unrealized “controlled fusion”

    This is an interesting development in the research area of Photoelectrochemical water splitting, but it's not about whether you can get hydrogen from sunlight. You could already do that, if you were willing to go from photovoltaics to electrolysis, or use solar energy for thermal water splitting. So, I think John is a bit over-enthusiastic.

    The real question is whether you can produce energy at economical rates, and I haven't seen any information on that. Given a competitive efficiency, it's likely that you could create such a system that's quite a bit cheaper than photovoltaics, but you still have to deal with the fact that solar energy is a fairly diffuse energy source. Time for a little math - how much space would it take to support an average household. Feel free to check my numbers...

    Picking a spot in California as a test case, we find that it averages about 5 KWh / sq meter / day.

    The average US household uses around 12000 KWh / year = 32.8 KWh / day

    So, if our system were 100% efficiency, we'd need about 6.5 meters of collector area. That sets a lower bound. Picking some more reasonable numbers:

    Light to hydrogen efficiency = 10%

    This seems like a fairly reasonable guess. Photovoltaics are in the same realm, and photosynthesis clocks in at around 8% for efficient plants.

    Hydrogen to electricity efficiency = 75%

    This is a harder number to come up with. There are claims of up to 80% here, so I'm going to choose 75% as a reasonable number.

    Power inverters (to go from DC to AC) are approximately 90% efficient.

    So, that makes our sunlight to AC power efficiency =

    0.1 * 0.75 * 0.9 = 0.0675

    Dividing our 6.5 meters by this factor gives us around 96 square meters of collection area required to take a California house off-grid. That's a collector that's properly aligned with the sun - being at the wrong angle reduces the efficiency.

    That's a pretty large amount of space.

    If, however, you can do this in large desert areas, you can get a megawatt of daytime hydrogen out of a collector that's about 150 meters square.

    There are also some interesting space applications. Presuming you can get water from asteroid sources, you could perhaps generate hydrogen and oxygen fairly simply.

  • Eric Gunnerson's Compendium

    Special birthday presents for her...

    • 15 Comments

    (Kim, make sure you don't read this, as it will ruin the surprise)

    My wife's birthday is coming up in a couple of weeks. I generally do a decent job at presents (how many other guys do you know that got their wife a trebuchet?), but I decided I needed some help, and went on over to FindMeAGift.com. Let'ssee what they recommend, shall we?

    Body Fat Monitor

    Yes, there's nothing that makes a girl happier than a gift that says, “you're carrying around a few too may pounds”. While you're at it, why not get her a copy of this book:

    That will really finish off the evening right.

    I don't think I'm going to be buying any of these, though giving the home DNA profiling kit is sure to make her wonder about your intentions.

  • Eric Gunnerson's Compendium

    Be a language designer redux...

    • 17 Comments

    Thanks for all the responses to the question that I posed. The reason I posed it is that I've been seeing a lot of language requests coming through the MSDN feedback site, which is a good thing, but some of them are pretty obviously impractical, so I wanted to try to explore a little of the "language designer" mindset.

    Several people pointed out that Cyrus had blogged about this a while back. That's true, though he doesn't explore things from a language designer standpoint, but rather from a language user standpoint. That's a nice place to start, but it doesn't really explore the areas you need to explore when thinking about adding a language feature.

    So, here's my analysis of the request. Note that I'm only one member (so to be an ex-member) of the language design team, so there may be other opinions...

    If you truly want to support non-null types, they need to be a runtime feature. That's the way that you get a secure, easy-to-use system that works the way users would want it to work.

    Unfortunately, at this point in time, it would be somewhat difficult for the runtime team to do it. Even if they did, it's really not practical to modify all the existing libraries to take advantage of such a feature, as that would pretty much require that every bit of .NET code be revisited/recompiled. If you changed String.IndexOf() to only take a non-null string, think of how many places that's used in the .NET universe.

    If we had it to do again, creating the runtime and CLR with such support seems like a good thing to do, but we weren't sharp enough to figure that out early on, so it's not something we can realistically add at this point.

    So, where does that leave us? Well, it is possible to approach this from the "parameter validation" perspective rather than the "not null type" perspective, and you can likely get the effect that you want (ie not having to write your own parameter validation code), though it's decidedly less efficient to check for null everywhere than to just know that null is not a possible value. We will be talking about the parameter validation scenario in future design team meetings.

    I think that Daniel O'Connell and Matthew W. Jackson probably came the closest to how I would approach the issue, so 250 points to each of them.

  • Eric Gunnerson's Compendium

    Another career option...

    • 17 Comments

    The first time, I thought it was a joke.

    I'd just written a short link post, and I'd gotten the following comment in my blog:

    When is the proper time to get up and leave the breakfast lunch or dinner table,whether it be with your spouse and childen and or company?

    I just figured that one of my readers was messing with me. Then there was another:

    My cousin is having an adoption party for her 3 sons that her present husband is adopting. What kind of gift would you give in this case?

    I appreciate your feedback....

    A quick look at my referrer page shows that I have a bunch of hits coming from Google - 250 or so right now. Turns out that due to my Google Karma, I'm the 8th most popular post on "Miss Manners".

    I ignored this for a few days, until I got the following email last Thursday:

    Sender: Ann
    Email address: <deleted>


    How does this work...I submitted a question, but I've noticed that none of the other questions posted on you site have been answered!!! I asked best way to say "no gifts" please.

    Hmm. Ann is serious, and apparently, so are the other 17 people who also asked me questions. Which therefore poses a bit of a dilemna:

    Should I answer them?

    I mean, I'm not an advice columnist, but many of these questions are pretty easy to answer. For example:

    Q: What is the proper language to use in asking your co-workers to support your child's fundraiser?

    A: Such language does not exist. Most co-workers likely have no connection at all to your child, and it's unfair to ask them to help support something your child is doing, especially in a way that might make them feel like they have to contribute. This is really bad if you're young and childless and all your co-workers have kids. Friends are another story, though one should also try not to impose.

    If there's a way to post something on a bulletin board or on your desk so that people can offer to donate if they want, I think that's okay.

    Q: What is most polite way to suggest "not" bringing gifts to an adult birthday party?

    A: People want to bring something to a party, and if you tell them to bring nothing, they won't feel as nice - especially if somebody else does bring something.

    Two ideas for getting around this:

    1. Make it a theme party. Ask everybody to bring a different bottle of wine for a wine tasting, or their favorite cheese, or something like that. Something cheap and consumable.
    2. Do something for charity. Write something like, "Since I have been lucky in life, I don't really need any presents, so if you wish, instead of a present please bring a blanket to donate to the homeless". Or do the same with food for a food bank.

    The danger, of course, is that I would hit the #1 spot on Google. In fact, merely the mention of "M. Manners" in this post might bump me up.

    Comments?

  • Eric Gunnerson's Compendium

    Blog to email gateway?

    • 18 Comments

    In talking with my mom a few weeks ago, I realized that readers of my blog know more about what's going on than my family does. Writing individual emails to them isn't going to happen, so I'm looking for a blog to email gateway. It should:

    1. Monitor a specific category in the blog for new posts...
    2. Create a templated email message from each new blog post...
    3. Send that email to a list of recipients...

    Anybody know of something that does this??

  • Eric Gunnerson's Compendium

    Practice your parking

    • 20 Comments

    http://www.ebaumsworld.com/pparkgame.html

    1:26

  • Eric Gunnerson's Compendium

    x+=x++;

    • 2 Comments

    Luca, who is taking over for me as C# Compiler PM, wrote this post:

    x+=x++;

    I heartily agree with him when he says "DO NOT WRITE THAT CODE".

  • Eric Gunnerson's Compendium

    Conditional Attributes

    • 7 Comments

    There's an extension to the conditional concept that shows up in Whidbey. It's not in Beta1 (well, to be more correct, it doesn't really work in beta 1), but it will be functional in beta2.

    If you put a conditional attribute on an attribute definition, that instructs the compiler to only place that attribute in the assembly if the symbol is defined. This allows you to have "debug only" attributes that don't take up space in your release assemblies.

     

  • Eric Gunnerson's Compendium

    RSVP 2004

    • 15 Comments
     

    Groupthink

    From Wikipedia, the free encyclopedia.

    Groupthink is a term coined by psychologist Irving Janis in 1972 to describe one process by which a group can make bad or irrational decisions. In a groupthink situation, each member of the group attempts to conform his or her opinions to what they believe to be the consensus of the group. This results in a situation in which the group ultimately agrees on an action which each member might normally consider to be unwise.

    ...

    It hit me about mile 50 on Friday. There was really no other explanation. I was riding north along highway 9, in the rain, as I had for the past three and a half hoursm, and it hit me.

    There was something wrong with me, with us, with all the riders around me. As I've mentioned in the past, there has to be at least something wrong with you to willingly put yourself on bike for 7 hours of riding, but granting that that is normal behavior, it's certainly less normal to do it in the kind of weather we had.

    But the majority of the riders not only decided to continue, they decided it was a good idea to continue. And continue we did...

    ...

    It had initially looked like a great weekend to be riding - the 90 degree weather had departed, and we were in a nice mid-70s pattern. Thursday was perfect, but the forecast was for showers. I trolled around to different news sites (what is King 5 TV thinking? - do they actually believe that I'm going to register just to get a weather forecast?), looking for better news. I finally ended up on the NOAA site, which said, "Likely to be the rainiest day of the summer".

    Damn.

    It's not that I hadn't ridden a fair bit in the rain this spring - I had. The problem is that when you're exercising hard, there's really no such thing as "breathable" clothing. You either have clothes that breathe well, but get wet quickly, or you have clothes that don't breathe well, hold in your sweat, and you also get wet quickly. Cycling makes this especially bad because you don't only get the rain, you get the spray off your tires. I put on my SKS Race Blade mini fenders Thursday night, which will keep the spray from my back tire off of my back, but it's won't keep the rain off totally.

    Friday I woke up to dry streets. Cool. But as I drove across the 520 bridge a few drops started to spatter on the windshield of the truck. Bad news. I got there at around 5:30, hoping to meet up with a friend to leave by around 6:00. For various reasons, we didn't get around to leaving until right at 6:30AM, as it started to rain. The first big hill of the day was up out of Woodinville, and I rode in my smallest gear, standing up here and there. Most of the riders were in pretty good shape. Along the segment from Snohomish to Lake Stevens, one of our team flatted, another went back to help her, and we rode on to wait at the stop. By this time I was really wet and cold on the arms (didn't put on my arm warmers), but relatively dry on my torso, and my leg warmers and neopreme boot covers were fairly dry. We waited at Lake Stevens (mile 30) for about 25 minutes, and by that point I was starting to shiver in earnest, so I told Bill that I had to bail, and rode really hard to get warm again. The ride to Mount Vernon wasn't much fun - I was reasonably warm, but you could either ride by yourself, or you could draft, and get a stream of road water into your face. I did a bit of both, and with my rear fender, I was pretty popular as a group leader.

    The last couple of miles into Mt. Vernon (70 miles) were over ground down pavement, and I think I got a big of taste of what it might be like to ride on cobblestones. Not fun at all, especially uphill, so I ended riding down the center turn lane. Suffice it to say that it was not the only time that I bent the traffic rules over the two days.

    The rest stop was a challenge. I needed to grab some food to supplement what I had brought alone (I get tired of sports bars and fig newtons after a while), and take a "nature break", but every minute off the bike I was cooling off. I got back on the bike after a bagel, a banana, an oreo, and a refill of my two litre camelback (I sweat a lot when I have my shell on). I was *really* cold when I left, and rode hard for 15 minutes to get warm again.

    And then something miraculous happened. As we rode to the west, the rain stopped, the skies cleared a little, and as the roads slowly dried, we did as well. I arrived at the base of Chuckanut drive - the last series of big climbs - in a group of 3 in good spirits, and rode the whole section with a rider who was doing RSVP as a training ride for a tour around Oregon. There are some painful climbs there, but none were too steep, and I made it into the finish at Bellingham in good shape, grabbed my backpack, and rode the 4 miles to my hotel (109.4 miles).

    Saturday dawned with drying streets, and I rode back up the hills to drop off my backpack (note to self - book your hotel early), and headed off towards the border. I hooked up in two or three good pacelines and we flew across the flats to Lynden at around 20 MPH (which is quite a bit faster than I'd ride by myself). There are two interesting things about the border. The first is that there's a road named "boundary road" that we rode on the US side, across the ditch, another road, this time in Canada. The second was my exchange with the Canadian customs officer:

    Her: Where are you going?

    Me: Vancouver

    Her: Where are you staying?

    Me: At a hotel, downtown.

    Her: What hotel?

    Me: I don't remember

    Her: Who made the arrangements?

    Me: I did. I just don't remember the name - it's in my bag.

    Her (shaking her head): Thanks. Enjoy your stay.

    The problem was that I was in the zone, and when I'm in that mode, I'm not spending a lot of time on rational thought - I'm just riding.

    The ride to the next rest stop (35 miles) was uneventfull, except for one really painful climb. I tanked up on water, ate a banana, and a bagel with peanut butter. The sun was intermittent, and it was wonderful. After the ride comes a short ferry trip, and then a ride up north, all the way to the Burrard inlet, for a final short rest stop (60ish miles). After a quick gel, I got on the Barnet highway, and realized two things.

    First, I only had an hour or so left. That was nice.

    Second, my legs felt really good. That was nicer.

    So, I decided to hammer (or do my best approximation) for the last hour. The Barnet highways is mostly up, with only a few downhills, and bears a striking relationship to one of my training rides in gradient, so I rode it hard, uphill from 10 to 15 MPH, and passed a lot more people than I expected. The remainder of the ride was up and down on the crest of the hills, down into Chinatown, where a group of 10 of us got lost together, and then finally screaming along the waterfront and up a hill to the finish.

    Overall, the ride was great. I felt good most of the time (with the exception of the rain), and the organization was really good, with the exception of a few marks that washed off in Vancouver. Kudos to the folks at Cascade.

    My training was about right, though I would have like to have ridden a bit faster (I averaged about 14MPH the first day, and the mid 14s the second day (lots of stop and go)). I may do it next year, and I have this crazy idea that I might want to do STP in one day next year...

  • Eric Gunnerson's Compendium

    6 stitches later...

    • 12 Comments

    It rained a bit here last night. Something like an inch and a half.

    The gutter by our outside window got clogged and overflowed all night. This morning, I went out to clean out the drains. Got the first one down (with my 28' extension ladder). Went to move the ladder, and it torqued out of my hands. When the top hit the ground, it spun the ladder around and whacked me in the ear. I went inside and layed on the floor while Kim applied direct pressure.

    So, I got to spend 2 hours in the emergency room, getting my ear stitched up. At least my Nurse Practioner was also a cyclist who had been in France for the tour, so we got to talk cycling while she stitched me up. Unfotunately, the only thing on TV was the Women's marathon. An hour of running doesn't make very good TV...

  • Eric Gunnerson's Compendium

    Museum of Flight - Personal Courage Wing

    • 4 Comments

    Yesterday morning Samantha and I went over to the Museum of Flight to check out the new Personal Courage Wing.

    The Personal Courage wing is a new two-floor exhibit dedicated to aviation during the first two world wars. The museum of flight was able to exhibit the collection of the Champlin Fighter Aircraft Museum on the condition that the provide a dedicated space for the aircraft, and it's fair to say that they've done that.

    In fact, I think this is one of the best museum displays that I've ever seen. The sound, lighting, and staging are all world class. From the world's first fighter plane that greets you as you enter the WWI section, the 1914 Caproni Ca 20, to the 400 MPH P-38L Lightning of WWII, everything is beautifully done.

    Recommended.

     

  • Eric Gunnerson's Compendium

    Best "Improve Your Dev Skills" books...

    • 23 Comments

    I've been looking through a few of my "Improve your Dev Skills" books:

    What are your favorite books in this genre? Why?

  • Eric Gunnerson's Compendium

    NUnit on Whidbey Beta 1 experiences...

    • 8 Comments
    I've been having problems getting NUnit to work on Whidbey Beta 1, and I'm curious what experiences you've had, either good or bad. Jim hasn't been having the same trouble, so we're trying to figure out what's what. For him, it works if he updates the config file, but I'm getting a BadImageFormatException.
  • Eric Gunnerson's Compendium

    Monkey Gallery

    • 1 Comments

    Jill Greenberg has turned her talents towards monkeys.

    from Boing Boing

    BTW, "Monkey Gallery" is a great name for a band...

     

Page 1 of 2 (39 items) 12