• Eric Gunnerson's Compendium

    HealthVault data type design...


    From the "perhaps this might be interesting" file...

    Since the end of the HealthVault Solution Providers confererence in early June - and the subsequent required recharging - I've been spending the bulk of my time working on HealthVault data types, along with one of the PMs on the partner team. It interesting work - there's a little bit of schema design (all our data types are stored in XML on the server), a little bit of data architecture (is this one data type, or four?), a fair amount of domain-specific learning (how many ways are there to measure body fat percentage?), a bit of working directly with partners (exactly what is this type for?), a lot of word-smithing (should this element be "category", "type", or "area"?), and other things thrown in now and then (utility writing, class design, etc.).

    It's a lot like the time I spent on the C# design team - we do all the design work sitting in my office (using whiteboard/web/XMLSpy), and we often end up with fairly large designs before we scope them back to cover the scenarios that we care about. Our flow is somewhat different in that we have external touch points where we block - the most important of which is an external review where we talk about our design and ask for feedback.

    Since I'm more a generalist by preference, this suits me pretty well - I get to do a variety of different things and learn a variety of useful items (did you know that you can get the body fat percentage of your left arm measured?).

    Plus, I learn cool terms like "air displacement plethysmography"

  • Eric Gunnerson's Compendium

    Seattle Century 2008 ride report

    Seattle Century 2008 ride report
  • Eric Gunnerson's Compendium



    Back when I first started listening to music - in the days before there were CDs - if you were cool you bought your music on records, and then taped them onto 90-minute cassettes. You did this because it was hard to flip a record while you were driving, records wore out, and pre-recorded cassettes sounded a bit like a 48kbs MP3 stream, when they worked. Sometimes they didn't, and you had a $8 cassette afro.

    Oh, and you had to worry about azimuth (an adjustment that, when wrong, could kill all your high end), Dolby B, and, if you were really cool, Dolby C (twice the Dolby!).

    And you listened to what was called "album rock" in my area, otherwise known as "progressive rock". Those who wish to debate the differences between those two labels are welcome.

    Then, I went off to college, and CDs were released, but the cost $900, so nobody had one (actually one guy in my dorm had one, connected to his $10K high-end system). So, we kept buying albums.

    Then prices came down, we got jobs, and we bought CDs of the groups we had listened to, and reveled in the CD experience. The sound was so much clearer than cassettes, that we didn't realize that a lot of the early transfers were awful.

    Over time, many of our albums got remastered - first by Mobile Fidelity Sound Lab (who had made some pretty killer vinyl recordings), and then by the labels as they realized there was some money in it.

    By this point, you're wondering if there is a point, or if it's just an onion belt.

    Anyway, I have a fair number of CDs that are early transfers, and I'd like to replace them, but it can be a bit of a pain to find out what specific albums have been remastered, when they came out, etc.

    Enter Progrography, which has a bunch of information about progressive rock, including re-releases. So, if I want to know what remaster to get for Who's Next, there's a page that gives me all the info. Well, some of the info - some of the pages are a bit out of date - but what's there seems to be pretty good.

    And if not, I can remember listening to AC/DC, which was the style at the time...



  • Eric Gunnerson's Compendium

    #region. Sliced bread or sliced worms?


    (editors note: Eric gave me several different options to use instead of sliced worms, but they were all less palatable. So to speak.)

    Jeff Atwood wrote an interesting post on the use of #regions in code.

    So, I thought I’d share my opinion. As somebody who’s was involved with C# development for a long time – and development in general for longer – it should be pretty easy to guess my opinion.

    There will be a short intermission for you to write your answer down on a piece of paper. While you’re waiting, here are some kittens dancing

    Wasn’t that great. No relation, btw.

    So, for the most part, I agree with Jeff.

    The problem that I have with regions is that people seem to be enamored with their use. I was recently reviewing some code that I hadn’t seen before, and it had the exact sort of region use that Jeff describes in the Log4Net project. Before I can read through the class, I have to open them all up and look at them. In that case, regions make it significantly harder for me to understand the code.

    I’m reminded of a nice post written by C# compiler dev Peter Hallam, where he talks about how much time developers spend looking at existing code. I don’t like things that make that harder.

    One other reason I don’t like regions is that they give you a misleading impression about how simple and well structured your code is. The pain of navigating through a large code file is a good reason to force you to do some refactoring.

    When do I like them? Well, I think that if you have some generated code in part of a class, it’s okay to put it in a region. Or, if you have a large static table, you can put it in a region. Though in both cases I’d vote to put it in a separate file.

    But, of course, I’m an old dog. Do you think regions are a new trick?

  • Eric Gunnerson's Compendium

    Taking on dependencies


    A recent discussion on how to deal with dependencies when you're an agile team got me thinking...

    Whether you are doing agile or waterfall (and whether the team you are dependent on is doing agile or waterfall), you should assume that what the other group delivers will be late, broken, and lacking important functionality.

    Does that sound too pessimistic? Perhaps, but my experience is that the vast majority of teams assume the exact opposite perspective - that the other group will be on time, everything will be there, and everything will do what you need it to do. And then they have to modify their plan based upon the "new information" that they got (it's late/somethings been cut/whatever).

    I think groups that plan that way are deluding themselves about the realities of software development. Planning for things to go bad up front not only makes things smoother, you tend to be happily surprised as things are often better than you feared.

    A few recommendations:

    First, if at all possible, don't take a dependency on anything until it's in a form that you can evaluate for utility and quality. Taking an incremental approach can be helpful here - if you are coming up with your 18-month development schedule, your management will wonder why you don't list anything about using the work that group <x> is doing. If, on the other hand, you are doing your scheduling on a monthly (or other periodic) basis, it's reasonable to put off the work integrating the other groups work until it's ready to integrate (based on an agreement of "done" you have with the other group).

    That helps the lateness problem, but may put you in a worse position on the quality/utility perspective. Ideally, the other team is already writing code that will use the component exactly the way you want to use it.  If they aren't, you may need to devote some resources towards specifying what it does, writing tests that the team can use, and monitoring the component's process in intermediate drops. In other words, you are "scouting" the component to determine when you can adopt it.


  • Eric Gunnerson's Compendium

    Why does C# always use callvirt? - followup


    I was responding in comments, but it doesn't allow me to use links, so here's the long version:


    Yes, marking everything as virtual would have little performance impact. It would, however, be a Bad Thing. It's #3 on my list of deadly sins... 


    cmp [exc], exc is the solution to the problem. It's there because that's what the JIT generates to do the null test.


    Yes, you are missing something. Methods need to be marked as virtual for them to be virtual methods - this is separate from emitting the callvirt instruction.


    I'm not sure I understand your example (why are you calling ToString() on b when b is already a string?). It seems to me that what you want can be handled through a method that tests for null and returns either the result of ToString() or the appropriate default value (String.Empty seems to be the logical one in this case).


  • Eric Gunnerson's Compendium

    Why does C# always use callvirt?


    This question came up on an internal C# alias, and I thought the answer would be of general interest. That's assuming that the answer is correct - it's been quite a while.

    The .NET IL language provides both a call and callvirt instruction, with the callvirt being used to call virtual functions. But if you look through the code that C# generates, you will see that it generates a "callvirt" even in cases where there is no virtual function involved. Why does it do that?

    I went back through the language design notes that I have, and they state quite clearly that we decided to use callvirt on 12/13/1999. Unfortunately, they don't capture our rationale for doing that, so I'm going to have to go from my memory.

    We had gotten a report from somebody (likely one of the .NET groups using C# (thought it wasn't yet named C# at that time)) who had written code that called a method on a null pointer, but they didn’t get an exception because the method didn’t access any fields (ie “this” was null, but nothing in the method used it). That method then called another method which did use the this point and threw an exception, and a bit of head-scratching ensued. After they figured it out, they sent us a note about it.

    We thought that being able to call a method on a null instance was a bit weird. Peter Golde did some testing to see what the perf impact was of always using callvirt, and it was small enough that we decided to make the change.

  • Eric Gunnerson's Compendium

    Looj Review


    As many of you know, we have lived with a Roomba for a few years. He's been a faithful servent, though our cleaning people sometimes unplug the charger and don't plug it back in.

    A while back I got an email that said "Looj on Woot!". Woot!, as many of you know, is a website that specializes in selling something different every day. And Looj is a gutter-cleaning robot from iRobot, the maker of the Roomba. A week or so later, the Looj showed up at my door, but I only got around to reviewing it today.

    Unlike the Roomba, the Luje is not authonomous. So, strictly speaking, it's a radio-controlled gutter cleaner rather than a robotic one, but I'm willing to cut them so slack on this. It has two parts - there's the main body of the robot, which is about 12" long, 2" wide, and perhaps an inch and a half tall. On the front is the cleaning part, which has rubber flaps and some strong brushes.

    Attached to the top is the handle/remote control.

    I got up on my roof today to try it out. I have a few leaves, a few needles, a bit of moss, and a whole lot of maple tree seeds (aka "helicopters"). It's all fairly dry because of the time of the year.

    To use it, you set it in the gutter, turn it on, and detach the handle. Turn on the auger, and then you just drive it forwards and backwards like an RC car. In most cases, it will clear all the debris in the first pass, but sometimes there's enough that it climbs on top a bit, and you have to reverse and then move forward to clean it all out. Or, you can drive forwards in spurts when you hit a lot of debris.

    It works really well. I only ran into two problems. In one of my gutters, the Looj rolled over on its back, but since the tread design is symmetrical, it works fine on the back as well. The second problem I had was when I drove it over a short maple tree which got tangled in the auger and the auger clutch released (this doesn't damage the Looj). I untangled it, pulled out the tree, and finished that section of the gutter (the Looj manual tells you not to try to remove trees...)

    So, I did all the gutters - perhaps 120' - in about 15 minutes. Now, I did it from the roof, so I didn't have to move the ladder, but it was still remarkably painless. And it's pretty cheap for what it does - about $100 for the basic model.


  • Eric Gunnerson's Compendium



    I was really just trying to get people to smile when they read about it.

    Last Sunday night (the 9th), I played another game of indoor. I felt pretty good, and though I got run into fairly hard at one point, I thought that the guy who ran into me came away worse than I did. At the end of the game my right ankle was sore, but everything else was fine.

    Tuesday morning, I woke up, and my side hurt. I tried to deny it, but by Thursday morning, it was clear. The guy who hit me must have run into me with a knee, because I have another hurt rib (on the lower-left quadrant - one of the short ribs, another new spot for me). I'm not sure whether it's bruised or cracked, but I do know that it's pretty painful. The 30 miles I did on the bike on Sunday were about as pleasant as 7 hills was (ie not much), and I skipped this Sunday's soccer game (it's better to spread the injuries out rather than enjoy them all at once). So, it's another 2-3 weeks of pain, though the only really bad time is when I first get up in the morning and stretch.

    The only upside for this is that I've been looking for a good excuse to skip RAMROD this year, and I figure the double-rib qualifies.

  • Eric Gunnerson's Compendium

    Conference wrap-up...


    After a bit of time to recover from my back-to-back conferences (TechEd 2008 in Orlando and the 2008 HealthVault Solutions Conference in Bellevue), I have a few thoughts to share.

    I haven't been to TechEd for a few years, but TechEd is still TechEd. The developer division, however, has seen a lot of turnover, and I was surprised to find how few Microsoft people that I knew were in attendence. I did two "lunch talks", which is code for "we don't know what track to put you in...". You only get 45 minutes for your talk (after which they come in and tell you to get off the stage), but on the plus side, you don't have to go through any slide review process. I did a HealthVault introduction that went relatively well, and a "write lots of code" talk that went well except for some demo slowness (more on that later). There were about 50 attendees in each session, which is pretty good for a lunch session because of the hassle of attending them.

    I'm disappointed that TechEd no longer devotes a night to "ask the experts". Instead, the MS people have to do "booth duty", which means you stand at your designated section for hours and hope that somebody will come by to talk to you. From watching and talking with a few MS people, that meant a lot of hours where you just stand around, and even when people come by to talk, the MS person who is best equipped to answer the question may not be there.  

    I talked with developers at all the meals, and had some good conversations. I ran into 3 developers who worked in the Health area but had never heard of HealthVault. It means we have some work to do to find out why those developers don't know about us, but it also means that we have some nice opportunities to reach a new audience.

    Splitting the conference into two sections (dev for 4 days, IT for 4 days) was a positive move for the people I talked to, and made it a bit more intimate (if you can properly apply that term in a conference that big).

    Two things I suggest not doing at a conference:

    First, don't try to write a presentation for a second conference while you are at a conference. It's really hard to do well.

    Second, don't check your bag at the conference center, unless you want to spend 35 minutes to do what will take you 5 minutes at the airport. The shuttles to the airport were nice, however.

    After the week at TechEd, I headed back for the

    HealthVault Solutions Conference

    Which was held Mon/Tue of the next week in picturesque downtown Bellevue (come see our construction) at the Hyatt Hotel. This was a great conference - everybody was uniformly friendly, and because of the partner approach the conference is as much about partner <-> partner interaction as it is about Microsoft <-> partner interaction. Monday featured a keynote and then a very complex demo involving live code from lots of different partners working together, put on by my team (but with very little effort on my part). The demo was nearly flawless, and if anything, they made it look a little too effortless. It was very compelling.

    Tuesday started with a keynote by Dr. Oz, a cardiac surgeon and gifted speaker. After a product roadmap talk (that I skipped to get set up for our technical track), we had the following talks:

    • An architecture talk by Bert and Sean
    • A data type talk by Tim and Eric
    • (lunch)
    • A development talk (same talk I did at TechEd) by Eric
    • A third-party-library and other topics talk by Chris
    • A Patient Connect talk by Kalpita

    The talks all went well, with the exception of Eric's. Apparently he forgot to modify his proxy settings to be used outside the firewall, so everytime he made a request it had to time out finding the proxy server before it completed. He is disappointed that he didn't figure this out before the talk, and apologizes to all those who put up with the slowness.  

    Our goal is to re-use the slides and get them on MSDN in some form. I'm probably going to take the development talk about make a tutorial out of it.

  • Eric Gunnerson's Compendium

    Answering a question nobody asked...


    I'm on a break between sessions at TechEd, downstairs in one of the cavernous halls. Something like 400 yards from from to back (yes, I paced it off). I was looking for a comfortable place to sit for a few minutes, and found that the MSDN Zone has a big space with about 20 bean-bag chairs in it. I walk around the side, and am surprised to find that there are a few empty ones. I gracefully lower myself - as gracefully as my middle-aged body will let me right now - and settle in.


    Apparently, somebody thought it was important to answer the question "what if I made something that looked like a bean-bag chair but stuffed it with cheap fiberfill instead?", and somebody else thought it was a good idea to answer the question "will people like these better than bean-bag chairs?"

    Questions that nobody had every really asked before, but for good reason. The whole point of a bean-bag chair is that the user gets to modify the chair to their own personal support requirements. If you want to flop out, you mush it out flat. If you want to sit up - and perhaps use your laptop - you smush it so that it provides good support.

    This "chair" is okay for flopping on, but despite a bit of swelling at one end, provides little in the way of support. After trying a few positions, I'm writing this while I'm in "street luge" position - my legs stretched out in front of me and my head just slightly raised up - which manages to look fairly relaxing without being relaxing at all.

  • Eric Gunnerson's Compendium

    Meet me at TechEd...


    If you're at TechEd this week and are bored Tuesday afternoon, I'll be hanging out in the community lounge (in the basement near the online labs area) during the afternoon.

    I'll try to make the 3-mile walk to the back of the basement room worth your while.

  • Eric Gunnerson's Compendium



    This spring I decided to start playing indoor soccer. I had played in the informal Microsoft outdoor lunchtime games a few years ago, but decided to do something different because a) it's hard to find time in the middle of the day, b) my group ride is Tue/Thu evenings, and iii) I might get wet and stuff.

    I needed to do something other than cycling because cycling specialists have trouble running to save their lives and have the bone density of 75 year old grandmothers.

    So, I signed up for the "over 40" league at Arena Sports in Redmond. We play on Sunday nights.

    The first few weeks were hard. My atrophied soccer skills were complimented by my disused running muscles and my untrained anaerobic system, but over time I started to make progress in all those areas, and the day at which I could actually walk without wincing became Monday rather than Thursday. I did get a rather spectacular skinned knee, and have therefore become a devotee of Tegaderm, a truly wondrous wound dressing (Seriously, it's great stuff).

    About 10 days ago, I scored two goals (one floater, one hard shot with a move before hand (I played defender for years, and my skill with "moves" is fairly limited)). I also left the field with Grade 1 Turf Toe, which was notably painful at the time. By Sunday, it was healed well enough that I could show with only a moderate lack of judgement, to play a double header. The games have blurred together, but both were against the top teams in the league and both featured some pretty skillfull players. Playing defense, I blocked one shot with my left leg, leaving a nice imprint of the ball across my knee. And I blocked another killer hard shot with my upper right chest, leaving me with...

    Longtime readers (Hi George and Fred) have probably figured it out already...

    Cracked rib.

    To go with #2 and #3. #1 is not chronicled yet, but involves people asking me if I was alright from a chairlift and lots of animated waving by me.

    This one - which I'm considering naming "Stanley" - is still in the "hurting more each day" phase, so it's not clear how it will compare to the others in terms of overall pain. Given how much it hurt to get out of bed today, I'd have to say I fancy its chances. I am happy that this is in a different place than the last two so the experience will be different.

    The *real* question is whether this is the "reason" (ie "excuse") I drop off of the waiting list for RAMROD.

    I'm going to ride 7 hills on Monday, doing a distant but undoubtably far whinier imitation of Tyler Hamilton in the 2003 Tour. The smart money is on the "7 hills" variant rather than the "11 hills" version, though some savvy betters have chosen "4 hills".

    To make it easier to track my rib-cracking antics (a pretty good name for a rock band), I've added the "CrackedRib" tag to my blog.


  • Eric Gunnerson's Compendium

    My TechEd Presentations...


    I've been working on my TechEd HealthVault development slides for the past week or so. I'm taking the "build an application from scratch" approach, which I think will work well but has a lot of interesting challenges.

    If you want to show up on Friday to shout helpful suggestions like "you forgot the semicolon" (ie "heckle"), here's the information:

    Dev Conference LUN05 Developing Microsoft HealthVault Applications
    Session Day/Time: 6/6/2008 12:00PM-12:45PM
    Room: S220 A
    Dev Conference LUN06 Introduction to Microsoft HealthVault
    Session Day/Time: 6/4/2008 12:00PM-12:45PM
    Room: S230 E (DEV)

    Note that LUN06 happens on Wednesday, and LUN05 happens on Friday, for a reason that I know better than to ask for.

    I will be there from Tuesday-Friday, so if you want to catch up and complain about how I don't write anything useful any more, let me know.



  • Eric Gunnerson's Compendium

    Individual Empowerment and agile...


    (Interestingly, I find myself writing more about agile and team stuff now that I'm not on a development team....)


    This is in response to a question about how you balance individual empowerment with the collaborative approach on a agile tem... 




    Agile is all about the team, and being on an agile team requires participants to give up some autonomy towards the team. The team is empowered to do what they need to do to reach their goal. If there are issues around how things should be done or what decision is right, the team needs to come to a decision, and I would encourage management to let the team try to do it.  Further, the team needs to “meta rules” around how to make decisions, and they also need to develop those.


    This is very different than the “alpha geek” culture that exists in some groups, where a small number of developers are interested in wielding power. There are some individuals who just aren’t willing/able to work collaboratively – I’ve worked with a few, and if you are trying to run an agile team, they are likely better in a different position.


    One of the teams I was on basically came to this agreement:


    Developers are expected to use their best judgement when deciding what advice to seek when they are doing development.   There are no rules around when you should seek advice, but as a rough guideline, extending functionality under existing patterns is something you can safely do on your own, and big refactorings or new components are areas when you should definitely seek advice. In between, think about the implications of any design choices you might make, and act accordingly.


    The other approach is to adopt pair programming, which is a bigger cultural change, but generally if you get two people thinking about decisions they usually make the right decision about involving others.

  • Eric Gunnerson's Compendium

    HealthVault Vocabulary Browser


    I wrote a little utility to browse vocabularies that I thought you might be interested in.

    It uses the HelloWorld app id, so you should just be able to dump it to a directory and run it.

    If you just want to browser, you can do it on the labs vocabulary page, or the vocabulary browser on Get Real's Developer's x-ray tool.

  • Eric Gunnerson's Compendium

    Being greener


    For most of my life, I've been a "small e" environmentalist. I'm not outspoken on my views, but I really hate to see needless waste. For me, that's meant keeping cars for a long time rather than replacing them, spending a little more on stuff that will last so I don't need to throw as much stuff away, and getting books at the library. Stuff like that.

    I haven't, however, put as much effort into applying the same principles to my profession, and over the past few months, I've been working to be more reasonable in that area as well.

    I've come up with a few practices that I thought I'd pass along, as part of what I'm calling "Green Programming - Simple practices to make the world a better place..."

    Practice #1:

    Consider the following code:

        if (x > 5)

    Now, if I need to change it so that 2 is added to the value of i rather than one, I would probably do the following:

    First, I'd select the line with the increment:

        if (x > 5)

    hit "delete":

        if (x > 5)

    and then type in the new line:

        if (x > 5)
            i = i + 2;

    I've done that sort of thing millions of times in my career. But not any more. Here's what I do now:

    First, delete the characters that I no longer need. In this case, it's just the second "+" sign:

        if (x > 5)

     then, insert " = i "

        if (x > 5)
            i = i +;

     and finally, " 2":

        if (x > 5)
            i = i + 2;

    In my first version, I deleted 12 characters (plus a carriage return and linefeed), and then added 20 new characters. With my new approach, I deleted 1 character and added 7 characters. That small change reduced my deletion percentage by 91.67%, and my new character percentage by a less impressive but still impactful 65.00%.

    Practice #2:

    The first practice made some great improvements, but I thought there was more to be had. I found that I could keep open a session of notepad, and rather than deleting the characters from my code, I would copy them to notepad, for possible reuse later. Unfortunately, since I write a lot of new code, I tended to exhaust this resource fairly quickly, and was forced to fall back on typing new characters.

    Practice #3:

    To give me a better source of recycled characters, I came up with a new approach. Not only do I copy characters to notepad before deleting them, when I need to delete a source file, I copy *all* of it's contents to my notepad buffer before deleting the file.

    I am proud to report that I now am justified in believing that I am "character neutral" in all of my coding. That made me quite happy, until I realized that I still had a problem.

    It was my blogging. I tend to write a fair bit on my blogs (3-5 depending on how you count them), but because of my natural eloquence and low quality standards, I rarely delete stuff, and therefore keeping a buffer for my blog writing was problematic. I tried using my programming one - it certainly is sufficiently full that it won't run out quickly - but I found that I tended to have some problems with expression ("I regret I have but one life to give foreach my country"), not to mention developing having to write lines like this:


    to use up some of the excess punctuation.

    So, that clearly wasn't workable, but just yesterday I came up with a great idea. I'm now recycling all the contact spam that is *already generated* by my blog into my blog buffer, and I'm considering re-using the splog links I keep getting, which would be especially convenient as they already have the words that I like to use.

    So, that's my little contribution, because as I like to say, if you're not part of the solution, you're part of the problem. Or the precipitate.

    Future Ideas:

    I haven't thought all of these through fully, but here's a list of other ways you might "recycle and reuse":

    • Don't throw away that command window you're using and create a new one. Reuse the existing one.
    • Keep old classes around to use as the starting point for new ones.
    • As some believe in "Peak Oil", I fear that we've already reached "Peak Guid", and that the days of $4 guids are in sight. I therefore recommend that you save all of the guids that you generate. Sure, it may be 15 years before the software that you used them in is gone and you're free to reuse them, but if you're the guy with 500 guids in your pocket during the Guid crisis of 2025, you're going to be sitting pretty.

    What practices can you add?

    (composed of 100% post-consumer characters)

  • Eric Gunnerson's Compendium

    Uncanny valley


    Try this on your second monitor...

    (yes, I know it's not fully rendered, but "Ew")

  • Eric Gunnerson's Compendium

    International Dance Party


    What a nice build. Make sure to watch the video:

    International Dance Party

     and you might want to take a look at the manual...

  • Eric Gunnerson's Compendium

    Project managers for agile teams...


    A recent question about skill requirements for project managers of agile teams led me to write this:

    In traditional project management, “project manager” means “person who is in charge”. In other words, that person makes the decisions, with varying degrees of depth (sometimes it’s high-level, sometimes it’s micro-management).


    Agile doesn’t have somebody in change – inherent in the concept of agile is that the group is responsible and the group decides.


    There *is* somebody who facilates (scrummaster in scrum, coach in XP), but their job is very explicitly not to make decisions. That means that the person who takes that role needs to be mindful of that and willing to push any decisions that rise up back down to the time. If the person has previous experience (and a preference) for “being in charge”, they are unlikely to do a good job in that role. If they aren’t thoughful about group dynamics in general, they may not do a good job in that role.


    Double that comment if the group is not experienced with making decisions together. If they tend to defer upwards and the facilitator is used to making decisions, you probably won’t get a good result.


  • Eric Gunnerson's Compendium

    Job openings in the HealthVault team...


    Long-time readers (who I like to refer to as "those three guys") know that I rarely blog about job openings, but I've decided to make an exception.

    The HealthVault team is building a platform to solve "real important" HealthCare problems that affect the lives of "real people". We're a small but growing group that still has that "new group" smell to it, and we're looking for people who would do well in that sort of environment.

    If you want to find out more information, you can find it at the Microsoft Career site (choose "Health Solutions Group" as the product). If you don't want to find out more information, you can find it at the bottom of a locked filing cabinet stuck in a discused lavatory with a sign on the door saying "Beware of the Leopard".

    Or so I'm told.


  • Eric Gunnerson's Compendium

    Scheming for Schema


    As many of you know, we already provide access to the schema for the healthvault types through the Type Schema Browser and the Raw XML API reference page.

    If those pages don't do exactly what you want - say, you want to look at all the schemas together in a tool - you can access the schemas programmatically. The schema for a data type is built on some lower-level schemas (or types, if you wish):

    The first one can be fetched programmatically, and the second and third you will need to download directly from the links I provided.

    Access to the schema is provided through the ItemTypeManager class. You can call GetBaseHealthRecordItemTypeDefinition() to get the base schema (base.xsd), and then use GetHealthRecordItemTypeDefinition() to get the xsd for a specific type.

    And, you can get a list of all the types from the "thing-types" vocabulary, thusly:

    Vocabulary thingTypes = ApplicationConnection.GetVocabulary("thing-types");

    Here's a bit of code that I wrote to fetch all of the schemas and store them in separate files:

        protected void Page_Load(object sender, EventArgs e)
            HealthRecordItemTypeDefinition baseTypes = ItemTypeManager.GetBaseHealthRecordItemTypeDefinition(ApplicationConnection);
            SaveTypeXSD(baseTypes, "base");
            Vocabulary thingTypes = ApplicationConnection.GetVocabulary("thing-types");
            foreach (KeyValuePair<string, VocabularyItem> item in thingTypes)
                Guid thingType = new Guid(item.Key);
                HealthRecordItemTypeDefinition definition = ItemTypeManager.GetHealthRecordItemTypeDefinition(thingType, ApplicationConnection);
                SaveTypeXSD(definition, definition.Name);
            int k = 12;
        void SaveTypeXSD(HealthRecordItemTypeDefinition definition, string name)
            string directoryName = MapPath("platform");
            string filename = MapPath(@"platform\web\xsd\" + name + ".xsd");
            using (StreamWriter writer = System.IO.File.CreateText(filename))
                string schema = definition.XmlSchemaDefinition;
    Note that it puts the schema definitions in a directory named platform\web\xsd. This is the same structure that the schemas use in our source tree, and this makes sure things work correctly
  • Eric Gunnerson's Compendium

    Work on your Vocabulary. The word for today is "CodableValue"


    Vocabulary and CodableValue are two of the somewhat interesting types in the HealthVault platform, and I thought I'd spend a little time discussing them.

    So, here's the problem they're designed to solve.

    In medicine, there are sometimes long lists. The kinds of lab tests you can order, the kinds of medication that can be prescribed, or the specialties of physicians. Unfortunately, the actual names can be a bit unwieldy. For the last example, you see things like:

    • Medical Toxicology - Emergency Medicine
    • Neurodevelopmental Disabilities (Pediatrics)
    • Adult Reconstructive Orthopedics

    So, to make things simpler, there are a set of codes - using one to three letters in this case - that are the "standard" ways of encoding the longer string (what I'll call the "Display Text"). Take that code, put it together with the display text (and sometimes an abbreviation), and you get a Vocabulary item. Create a list of a bunch of VocabularyItems (along with some other information I'll talk about in a minute), and you get a Vocabulary, which defines both a list of possible options and the accepted way of encoding them (the key).

    To be a bit more concrete, here's how we can fetch a vocabulary describing the different kinds of aerobic activities:

    Vocabulary vocabulary = ApplicationConnection.GetVocabulary("aerobic-activites");

    foreach (KeyValuePair<string, VocabularyItem> item in vocabulary)
        string key = item.Key;
        string displayText = item.Value.DisplayText;
        string abbreviation = item.Value.AbbreviationText;

    If you looked closely at the foreach part, you noticed that item.Value is really a VocabularyItem, and that's where DisplayText and AbbreviationText came from.

    Here's what I got back from executing that code:


    Key DisplayText AbbreviationText
    run running run
    jog jogging jog
    hike hiking hike
    bike bicycling bike
    spin spinning spin
    swim swimming swim
    walk walking walk
    row rowing row


    In addition to the information on a specific vocabulary item, there is some general information on the Vocabulary type.


    The culture tells you the culture of the vocabulary. When you fetch a vocabulary, it comes back for the current Culture, and you can control whether there is a fallback to other culture's if there's not one specific to the current culture. Note that the key is culture-invariant, and therefore may not make sense to users in your current culture.


    Family defines the overall source for the vocabulary. If it's from HL7, this would presumably be for that. Or perhaps it might say "AMA", or something else. The family lets you understand where the vocabulary came from.  If it's something the HealthVault team defined, the family is "wc".


    The name of the vocabulary. Together with the family, that should fully identify the source


    A string defining a version of the vocabulary.  


    Coded and Codable Values

    How is a reference to a specific vocabulary item stored in HealthVault?

    It is done through the CodedValue type. A quick look at the type shows the following properties:

    • Family
    • Value
    • Version
    • VocabularyName

    As you probably figured out, Family, Version, and VocabularyName are used to indicate what vocabulary we are using, and Value is used to store the key for the specific vocabulary item. An application can figure out exactly you mean by looking at the CodedValue.

    That works well when we have a vocabulary and we know exactly what code to use. But there are two more scenarios we need to support.

    First, we might have an item to store, and it's either not in the vocabulary or we don't know what the appropriate vocabulary is. I might want to store my juggling exercise data, but that's not part of aerobic-activities vocabulary. Or, I'm adding the over-the-counter allergy medicine I take, and all I know is the name on the box.

    In other words, sometimes we have very precise information, and sometimes it's less precise, but in both cases the platform and the applications that use the platform need to handle it well.

    The second scenario - and this one's rarer - is that there are times where a single entry might need to store multiple values.

    Both of these scenarios are supported through the CodableValue type, and that's the type that you'll see used in the data types.  It provides a Text property and a way of having multiple coded values.

    CodableValue.Text is always set for all codable values, and that's the one that you display when you're showing that value to a user. Any underlying CodedValue instances are of a "more information" category - the application can use them to find out more information about that Text.

    All Vocabularies

    You can fetch the list of all vocabularies with the following:

    ReadOnlyCollection<VocabularyKey> keys = ApplicationConnection.GetVocabularyKeys();

    Why would you want to do this? Well, it's useful for browsing to see if the vocabularly that you want is currently defined in the system. If there's one that's not in the system, you can request a new vocabulary using the same process you'd use to request a new data type.

    Best Practices

    1. Always set the Text property on the Codable value, even if there are CodedValues underneath.
    2. Always display the Text property as the high-level summary of the CodableValue.
    3. Be thoughtful about displaying the key to a vocabulary item to the user. It might be a number - in which case it is probably okay - but it also might be a string that only works well in one locale.  


    One of the nice things about vocabularies is that there is are so many to choose from. There are several different coding systems - and therefore possible vocabularies - for medication. We've talked about providing translation services between different vocabularies - so that an application could easily get hte information in the vocabulary it understands best.

    Would you find that to be a useful feature?

  • Eric Gunnerson's Compendium

    Dealing with PersonalImage


    PersonalImage is a type that encapsulates the picture that shows up for a person in the health record.

    My current image is this:

    With the power to... Melt!

    (those interested into why that is my current image should post the results of their research in the comments)

    PersonalImage is what is called a Singleton type, which - as you've probably already figured out - means that there can only be one of them. But, there might be none of them, so code needs to handle this case as well.

    Here's some code you might find useful.

            using (Stream imageStream = System.IO.File.OpenRead(@"C:\Documents and Settings\ericgu\My Documents\My Pictures\213.jpg"))
                HealthRecordItemCollection collection = PersonInfo.SelectedRecord.GetItemsByType(PersonalImage.TypeId, HealthRecordItemSections.All);
                PersonalImage image = null;
                if (collection.Count != 0)
                    image = collection[0] as PersonalImage;
                    using (Stream currentImageStream = image.ReadImage())
                        byte[] imageBytes = new byte[currentImageStream.Length];
                        currentImageStream.Read(imageBytes, 0, (int)currentImageStream.Length);
                        using (FileStream outputImage = System.IO.File.OpenWrite(@"g:\213.jpg"))
                            outputImage.Write(imageBytes, 0, imageBytes.Length);
                if (image == null)
                    image = new PersonalImage();
                    image.WriteImage(imageStream, "image/jpg");
                    image.WriteImage(imageStream, "image/jpg");
  • Eric Gunnerson's Compendium

    HealthVault and openness


    Yesterday - while I was taking a day off skiing with my wife and daughter - we announced our plans around openness and interoperabiity for HealthVault.

    I'm pretty excited about this. I'm especially excited about making the current .NET client library available under the Microsoft reference license, as I remember how useful it was to step through the MFC or ATL source when I was trying to figure out how things worked (or, more usually, what I had done wrong).

Page 5 of 46 (1,144 items) «34567»