# Friday, November 11, 2005

What does the following C# code do? Guess and then run it.

using System;
using System.Threading;

namespace AnonMethods
{
class Program
{
static void Main(string[] args)
{
for (Int32 i = 0; i < 20; i++)
{
Thread t = new Thread(delegate() { Thread.Sleep(10); Console.WriteLine(i); });
t.Start();
}
Thread.Sleep(5000);
}
}
}

We were playing with this and similar code in the experts area at the Ottawa VS launch yesterday. Fun, fun.

My task ahead is to find a scenario that makes the subtleties of anonymous delegates useful. Anonymous delegates are certainly useful. It is the trick above with "i" that I'm talking about. I'll post in a couple days with more data on what is going on.

Friday, November 11, 2005 2:51:50 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 

Today marked the second of ten stops on the Canadian launch of VS 2005, in Ottawa. You can check out launch pics @ flickr. Looks like the pics are limited to Toronto at this point, but I expect that to change over the next few days.

 

The Ottawa launch was another success. It was definitely more cozy than Toronto, being in a hotel, rather than a convention center. This different actually had its benefits. Faces started looking familiar more quickly and people didn't get lost ;)

 

The ask the experts area was staffed by a bunch of the same experts as Toronto. By the second go, we definitely had our act together. For example, we did a better job of getting the best person to answer questions. I don't know a lot about databases or of our System.Data classes. Fortunately, Bruce Johnson did, another .Net expert from ObjectSharp.

 

I managed to break away from the experts area for a while to go see one of the talks. Gotta say that Jerome and Barry did a great job. John also did a great job during the keynotes. I didn't get to see him in action during the talks.

Friday, November 11, 2005 6:33:25 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

The Ottawa launch started with us arriving in town last night. Ottawa is one of my favourite cities in Canada, and certainly my favourite in Ontario. As a result, I was really looking forward to it. The trip started a little rough with a couple flights to Ottawa being cancelled and then me forgetting my jacket at gate 122 in Toronto airport. The dumb part is that they announced a lost jacket just before the plane left the gate (with everyone seated), but I was already deep into conversation with my two seat-mates. Anyway, a quick call to Toronto Airport from Ottawa solved the problem after I was patched back through to gate 122. The jacket was there and we were good to go. My Swanndri jacket is particularly important to me as I picked it up when Annie and I were married in New Zealand five years ago.

We drove from the airport to Microsoft Canada. We were late and were denied admittance at first by building security at Microsoft Ottawa. Note that the building has several tenants, so security was not MS-specific. Anyway, we explained the situation and got past that. Odd. We then spent the next hour with a bunch of local Ottawa .Net folks. We had some great conversations with the local developers over beer and cheese. I spent about 30mins talking with one guy in particular. We had a very interesting conversation about dynamic languages and some of the subtleties of anonymous delegates and methods in C#. I certainly knew about anonyomous delegates, but didn’t know about the subtleties that he mentioned. We talked more about the way that these work today at the launch and I now have a better idea. I’ll post more on this later.

After the beer and cheese, we headed to dinner with Barry Gervin of ObjectSharp. He's the left-most guy in this pic. Definitely a very smart guy. He's a regional director for a bunch of Microsoft technologies and also seems to like Italian food.

Friday, November 11, 2005 5:55:22 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 10, 2005

Wow! The Toronto launch was pretty amazing. There were apparently >3000 people there. The keynote presentation was pretty good. It was more marketing-oriented than anything technical, which is to be expected from a launch event.

 

I really enjoyed the ~5 3-5 minute videos that they played at the launch. For me, they are more interesting than slideware and also much more compelling. “Here are some real-life customers who might even be part of your industry who are using Visual Studio 2005 and .NET Framework v2.0.” About half the videos were of American or International companies. The other half was impressively Canadian. I was surprised and very happy that Microsoft Canada had taken the time to create videos of customers using VS and the .NET Framework from all over Canada. Being Canadian, that really helps make the whole thing more credible.

 

Also, all the speakers wore poppies. Nice touch guys. I’m sure that I wasn’t the only one who noticed that detail. This attention to detail was most impressive to me with Craig (Symonds), who like me is Canadian but came from out of town (Redmond). With all the last minute details related to the launch, I could easily see how he would have forgotten to wear a poppy. I’m sure that the launch team helped with that, but it was still a nice touch.

 

Anyway, on to the more interesting data. The whole event started off with a keynote. It was dark in the big room with lots of flashing lights and these huge clear balls with some kind of wide tinsel flying around side, bouncing from one side of the building to another. Wild. You can get an idea of the excitement in the room via the picture below, taken about 20mins before the event actually started and before everyone got into the room (hence the empty chairs at the back).

 

keynote room 

 

I didn’t go to any of the sessions. I had the pleasure of hanging out in the Cabana or “Ask the Experts” area. I was there for several hours straight – even during lunch – answering many many questions of the folks that came in. There were 20 or so “experts” in the room, but it seemed like folks were lined up most of the time, waiting to talk with us. It was actually pretty crazy. There were a bunch of questions that I couldn’t answer, being too far out of my area. As a result, I handed out about 30 or so business cards, asking people to contact me later with their questions, which I would then hand off to the actual experts.

 

Several folks commented that the major value for them was the experts area. They definitely got value out of the other aspects of the event, but were able to drill down pretty deeply into areas that mattered to them with the experts. Very cool. See a pic of the experts area below.

 

cabana area

 

To end the day, we (all 3000+ of us) got a grab bag with VS 2005 and SQL Server 2005 (both standard non-trial versions). I imagine that a lot of folks were pretty excited by that. They already could download the Express SKUs from MSDN, but getting the real thing is a pretty cool deal.

 

I met with two companies today in Toronto, both banks. It is interesting to see what kind of projects that they are taking on and where they are and are not choosing to use the platform. In most cases, the “are not” scenarios are mostly for historical reasons and will change over time. It is most interesting to see where their pain points are. We’re about to start a new release and have the opportunity now to look at addressing significant problems. For the last year, we’ve been pretty locked down on Whidbey, not allowing us to implement significant solutions to issues that customers have encountered. It is a breath of fresh air to be in a different mode. I’m looking forward to meeting with customers, learning about what sort of improvements/features that they want and then brewing that all up in the feature mash to come up with something great for CLR v3.

 

I’m in the airport right now, waiting to head out to Ottawa in about 40mins. The flight is ~60mins. At 6 (or as soon as I can get there since I’m landing at 5:40), I’m going to attend another pre-launch event at Microsoft Ottawa. I’m guessing that this is going to be another “Beer and Cheese”. We shall see.

 

The MVP/Influencer type events are generally my favourite. The folks that attend them have generally invested a lot of time and passion into .NET development, so by definition have a lot of depth and opinion on the subject. As a result, you can have some pretty interesting conversations with these guys. They also don’t hesitate to push back on certain things. Constructive (and sometimes not that constructive) criticism is very helpful and does affect the designs that we decide on and implement.

 

And of course, I’m really looking forward to the launch event tomorrow! See you there.

Thursday, November 10, 2005 4:39:58 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 08, 2005

I just got back from the pre-launch event. It was pretty much a "beer and cheese". Got to love those. We're doing them all the time in Redmond.

I got talking to a few guys for most of the time. It is amazing to hear folks from back home speaking so authoritatively about the platform that you work on! John, pictured below, had a lot of interesting things to say about ASP.Net. I definitely understood where he ws coming from and had had some of the same experiences. He also made some interesting comparisons with Ruby. It certainly does seem like dynamic/scripting languages are rising in popularity.

Here's a picture of the 3 guys I talked to most. Of the 4 guys pictured, I'm the one on the left with the brown shirt. The other guys from the left are Obi, Richard and John.

geek power

Time to go to bed. I'm still on Pacific time, but won't feel much like that when I need to get up on Eastern time for the launch!

Tuesday, November 08, 2005 6:02:07 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 

I started my day at 6AM, which is earlier than normal. I haven’t set the alarm for work since my daughter was born, always waiting for her to wake us up, which is generally earlier than desired. The alarm and 6AM wake-up didn’t hurt much though.

 

The cab came by at 7:10AM, 20 mins late. That was OK though, as I booked it 10mins earlier than I needed. Also, my daughter didn’t wake up until 6:55, so I would have missed her by 5 mins if the taxi had arrived on time, which would have put a lot worse feeling on the day.

 

For some strange reason, I opted to fly to Vancouver and then to Toronto. We always fly direct on Air Canada from SEA (Seattle) to YYZ (Toronto). Actually, I didn’t choose to do it; it was a mixup on my part of understanding how to use our travel booking website. Better luck next time. It adds 3 hours (or so) to the trip to Toronto, but that’s OK. Vancouver airport is one of the nicest that I’ve ever had the pleasure of visiting. Seattle’s is pretty bad in comparison.

 

Now I’m on the flight from YVR (Vancouver) to YYZ. Interestingly enough, Air Canada decided to cut free in-flight meals last week. I applaud the change, actually. I care a lot about the food I eat, both from the standpoint of nutrition and taste. Airplane meals, as you know, generally lack in both categories. It would be great if appropriate price cuts accompany the reduction of service.

 

The guy just came by asking “anything from the restaurant”. Last time I checked, a rolling cart with a bunch of pre-packaged food on top didn’t count as a restaurant!

 

I opted for lunch at Whitespot, a household name in Vancouver. They even have Whitespot available on the BC fairies. I opted for a veggie burger and a salad. I’m feeling pretty good about that after seeing what folks are ordering on the flight. Maybe next time, I’ll bring a steaming Indian curry on to the plane. Either that or a Coleman stove and a filet of salmon to bake.

 

Enough of the logistics … I’m really looking forward to the launch. I’m heading to a pre-launch event at a restaurant on Dixon (Lonestar Texas Grill) as soon as I land. I believe that I land at something like 7:24PM and the event starts at 7:30PM. Watch in-flight feature film “Must love dogs” à Land à Deplane à Get baggage (1 item) à Get Taxi à Enter restaurant à Order supper à Watch meal get cold as I talk Whidbey with .NET MVPs.

 

Craig Symonds is doing the keynote tomorrow in Toronto. Craig is the General Manager of the Visual Studio division. Surprisingly enough, they produce this thing called Visual Studio. I’m in its sister/brother division called NDP or .Net Developer Platform, which produces the .NET Framework. I don’t exactly work with Craig, as he’s an executive and I’m an “individual contributor”. That being said, I work with folks from his division all the time, generally working on two things: designing/implementing VS/.NET Framework integration and determining which product a given bug resides it (it often isn’t clear on first look). Actually, the last part is the most interesting to me. More on that another time.

 

Last I heard, there are four or five thousand people registered for the Launch event in Toronto. I also heard – and I think that this is amazing – that all attendees are being given a fully-fledged version of VS 2005 and SQL Server 2005. Wow! The VS version is apparently a “special edition”. I have no idea what that means, but the product is apparently not time-bombed or crippled in any way. It might just be a special box, which would actually be kinda cool. I have a special Windows XP box that I was given for working on that, and I still get a kick out of that.

 

Hope to see you there … or in Ottawa a couple days later.

Tuesday, November 08, 2005 1:09:13 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, November 03, 2005

I'm being sent to Toronto and Ottawa to participate in the VS 2005 launches there. I guess I was picked since I'm a native speaker ;)

If you are going to be there too, it would be great to meet up to talk about Whidbey. I believe that I'm going to spending most of my time at the "Ask the Experts" desk/area/table. Come by to chat, ask questions or bring your laptop stopped at your favourite breakpoint in the VS debugger.

I also have a bit of time on the 8th and 9th (in Toronto) and 10th and 11th in Ottawa if you'd like to meet to talk about .NET Framework development that you are (or are planning to be) doing. Please mail me @ rlander@microsoft.com if you'd like to meet (at the launch location, Starbucks or your location).

I'm also planning to attend the Vancouver and Calgary events. I'll post more on that after the Ottawa and Toronto events.

Thursday, November 03, 2005 9:58:12 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, October 04, 2005

It’s high time for the next installment in this series. I was planning on getting to it sooner, but I’ve had a bunch of crazy things going on to do with getting the .NET Framework integrated into Windows Vista and planning for the next couple versions of the .NET Framework. None of that is calming down, but it’s time to get out another installment none the less.

 

I took a quick and somewhat vague look at type forwarders in my previous post (on purpose). Some of you were likely satisfied by that level of information and others are likely interested in more detail. As the title of this post suggests, this is the place to get more detail. To best do this, I’ve created a simple – and not particularly useful – application to demonstrate how forwarders really work. I’ll include this app in my next post.

 

Here is the entire program (it is only the Main method):

 

using System;

using StringUtilities;

using MathUtilities;

 

namespace TypeForwarderApp

{

    class Program

    {

        static void Main(string[] args)

        {

            Int32 int1, int2, intSum, stringCharacterCount;

            String initialString, reversedString;

            String appMessage;

 

            appMessage = "This app doesn't really do anything useful";

            Console.WriteLine(appMessage);

 

            int1 = 16;

            int2 = 14;

 

            initialString = "Happy 30th Birthday Microsoft!";

 

            intSum = MathUtil.Add(int1, int2);

 

            reversedString = StringReverse.GetReversedString(initialString);

            stringCharacterCount = StringCharacterCount.GetCount(initialString);

 

            Console.WriteLine();

            Console.WriteLine("Initial String : {0}", initialString);

            Console.WriteLine("Reversed String: {0}", reversedString);

            Console.WriteLine("String Length  : {0}", stringCharacterCount);

            Console.WriteLine();

            Console.WriteLine("Integers: {0}, {1}", int1, int2);

            Console.WriteLine("Sum     : {0}", intSum);

            Console.WriteLine();

            Console.WriteLine(StringReverse.GetReversedString(appMessage));

 

 

        }

    }

}

 

Like, I said, the program doesn’t do anything useful. I included the birthday message given that two Fridays ago was the annual Microsoft company meeting at SafeCo Field in Seattle. The theme was “Beyond 30” celebrating the first 30 years of Microsoft, although the content was much more about the future than the past (which I imagine most folks there appreciated). The 25th anniversary meeting was much more of a history lesson. I think that was the one that Sinbad was at ;)

 

I’m going to concentrate on one type, the StringCharacterCount type. At the moment, it is part of the StringUtilties assembly. If we look at the MSIL code within TypeForwarderApp.exe, we’ll see that clearly.

 

This is the MSIL code within the exe that calls the static method GetString on the StringCharacterCount type:

 

  IL_0030:  call       int32 [StringUtilities]StringUtilities.StringCharacterCount::GetCount(string)

 

As you can see, the fact that StringCharacterCount lives within the StringUtilities assembly is pretty apparent. Actually, you could go as far as saying it is hard-coded. Hence the need for forwarders …

 

Well, I’m a typical developer and I’ve decided in my second version of StringUtilites and MathUtilites – I happen to own them both – that StringCharacterCount is really a math utility and less of a string utility. As a result, I’m going to move this cool type to the MathUtilities assembly.

 

I just moved it to the MathUtilties assembly. You can see that it is indeed part of the MathUtilities assembly via the MetaInfo (CTRL-M) view in ILDasm.

 

TypeDef #2 (02000003)

-------------------------------------------------------

      TypDefName: StringUtilities.StringCharacterCount  (02000003)

      Flags     : [Public] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100001)

      Extends   : 01000001 [TypeRef] System.Object

      Method #1 (06000003)

      -------------------------------------------------------

            MethodName: GetCount (06000003)

 

Notice that the StringCharacterCount type is still part of the StringUtilities namespace and not MathUtilties. This is for two reasons: the namespace is part of the type name and type forwarders do not change the type name in any way. Put another way, if I moved StringCharacterCount from the one assembly to the other *and* changed its namespace, then I would have a breaking change that even type forwarders could not mitigate.

 

This all makes sense, but we have yet to see the interesting part. What does the metadata within the new version of StringUtilties look like? Let’s take a look at the manifest (another ILDasm view) within the StringUtilties assembly. There are actually two additional directives that we didn’t have before.

 

.assembly extern MathUtilities

{

  .ver 1:0:0:0

}

.class extern forwarder StringUtilities.StringCharacterCount

{

  .assembly extern MathUtilities

}

 

StringUtilties now has a dependency on MathUtilties and there is this “.class extern forwarder” line for “StringUtilities.StringCharacterCount”. Clearly, we’ve hit our jackpot. The dependency on MathUtilities is clearly required, given that StringUtilities intends to forward to it. The second directive, the class directive, is a way to signal to the runtime that the assembly knows about the class, but that it is located at another location.

 

If we look further yet, we’ll see that there is an entry in ExportedType table.

 

ExportedType #1 (27000001)

-------------------------------------------------------

      Token: 0x27000001

      Name: StringUtilities.StringCharacterCount

      Implementation token: 0x23000002

      TypeDef token: 0x00000000

      Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [Forwarder]  (00200000)

 

We’re now looking at metadata instead of the MSIL view (the directives) above. The ExportedType table is generally used to publish all the types in child netmodules of an assembly – build a multi-module assembly and you’ll notice this first-hand. In the case of multi-module assemblies, the implementation token would point to the netmodule, not to a separate assembly. In the case of type forwarders, the implementation token points (naturally) to a separate assembly. We can easily prove that too. Look at the AssemblyRef entry for the MathUtilities Assembly below.

 

AssemblyRef #2 (23000002)

-------------------------------------------------------

      Token: 0x23000002

      Public Key or Token:

      Name: MathUtilities

      Version: 1.0.0.0

      Major Version: 0x00000001

      Minor Version: 0x00000000

      Build Number: 0x00000000

      Revision Number: 0x00000000

      Locale: <null>

      HashValue Blob:

      Flags: [none] (00000000)

 

Notice that its token (0x23000002)  matches the implementation token of our forwarded type (0x23000002). There you go. That’s it! Now you know everything I’m going to tell you about type forwarders.

Tuesday, October 04, 2005 4:18:21 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, September 14, 2005

Type forwarders are an interesting feature. If you’ve never needed them, you’ve probably never thought about or imagined them. They were designed to allow developers to move types from one assembly to another without breaking existing code that was dependent on types living within a particular assembly. There are a bunch of reasons why you might want to move types around; however existing type references will make that problematic.

 

You may be thinking “I move types between assemblies all the time and nothing breaks”. That may be true if you are building applications that happen to have dependent assemblies. At the point that you build frameworks that other developers build apps on *and* you distribute those libraries as pre-compiled binaries (not as source) *and* you promote apps built against earlier versions of your framework to newer versions (say with publisher policy or binding re-directs) without re-compiling apps, then you can easily run into this problem.

 

The .NET Framework hits this scenario dead-on. Everett apps, when run on Whidbey (i.e. Whidbey-only machines), for example, run against the Whidbey .NET Framework libraries. That work without issue, but those Everett apps still expect types to be in the same place as they where in Everett, which in the case of System.String is mscorlib.dll. If we moved System.String to system.dll, for example, we’d break 100% of Everett apps run on Whidbey. Why? The CLR loader would no longer be able to resolve the type reference – [mscorlib]System.String -- stored in the app’s metadata, but instead would throw a System.TypeLoadException exception. The app wouldn’t like that and neither would it’s users ;)

 

Before anyone gets the wrong idea, we didn’t move System.String or any other existing types in Whidbey. I’m merely using the .NET Framework as an example of how framework developers could similarly run into this problem, which would be the precursor for needing type forwarders.

 

Enter type forwarders. Type forwarders are a new MSIL directive that essentially say “type x used to be in this assembly, but it is now in this other one. Maybe you should go look over there”. Let me just show you.

 

  1. Create type t1 in assembly asm1
  2. Create an app that uses [asm1]t1 (that’s just short-hand for saying type t1 that lives in assembly asm1)
  3. Run app.
    1. Loader loads asm1
    2. Loader loads t1
    3. Everything works
  4. Close app and move back to VS 2005.
  5. Move type t1 from asm1 to asm2 (these will be two different projects)
  6. Create a forwarder in asm1 that points to [asm2]t1
  7. Recompile asm1 and asm2. Do not recompile the app.
  8. Run app
    1. Loader loads asm1
    2. Loader notices forwarder directive in asm1, pointing to asm2
    3. Loader loads asm2
    4. Loader loads t1 (this time for asm2)
    5. Everything works

 

You do need to realize though that forwarders are really just a temporary crutch for older apps. Notice that we didn’t re-compile the app above. That’s actually the point of the whole scenario. We’re assuming that we don’t have the option of re-compiling the app, because we don’t own it – in this scenario, we own the framework, not the app. When the owner of the app does get the chance, we get the following list of activities:

 

  1. Re-compile app against the latest version of asm2
  2. Run new version of app
    1. Loader loads asm2
    2. Loader loads t1
    3. Everything works

 

Notice that we no longer visit the forwarder in asm1. When the app owner re-compiled the app, the compiler found t1 in asm2. As a result, we no longer needed the mis-step in asm1. Like I said earlier, forwarders are merely a crutch for apps compiled against older versions of your framework. Once the apps are re-compiled against the new version of your framework, the forwarder is no longer needed (for that app). Unfortunately, you’ll need to keep that forwarder in place for some time, as there are likely a whole host of other apps and add-ins to those apps still reliant on the forwarder to work properly.

 

My next post will deal with the details of forwarders and I’ll post some source that uses the feature.

Wednesday, September 14, 2005 8:30:12 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, September 13, 2005

My last “Wonders of Whidbey” series seemed to be quite well received, at least in terms of aggregator traffic, so I thought that I’d do another one. This time, I’d like to talk about the new factoring features in Whidbey. This topic has been bouncing around my head now for quite some time, so it was easy to choose. I also have the next WoW series picked out, but you’ll have to wait a little longer for that one.

 

I’d like to give you some insight into these features first. I’m a little vague on the birth (early 2003?) of these two features, since I was not on the CLR team yet, but working in another part of Microsoft at that time. I joined the team in November 2003. In early 2003, a subset of the CLR team (and a bunch of other folks from across the company) was working on some major improvements to managed code versioning. They had a particular take on the problematic parts of the current versioning system and had come up with quite an interesting solution. As part of that, the team was going to do some serious factoring (moving types between assemblies) of the .NET Framework, but that approach would have the negative effect of breaking pretty much 100% of existing applications since type references included the assembly identity. As a result, the team developed some cool factoring features in the CLR to mitigate those problems.

 

We’re no longer going down the same path with versioning as we thought we were back in 2003, but we’ve kept the factoring features in the product. We do have some other uses for these features, but they are not quite as far reaching as the earlier versioning plan. I think that Microsoft platform teams are realizing, more and more, that many of the engineering problems that they face are not unique to Microsoft, but are also faced by other software companies. That realization is actually the basis of the Visual Studio Team System products in a lot of ways. That’s a long way of saying that we’ve kept these factoring features in the product, believing that they will be useful to enough managed code developers out there. That being said, I don’t expect a lot of folks out there to use these features. In fact, I’m hoping that adoption of these features is left to niche scenarios, as I can imagine some folks painting themselves into some bad corners if they do not use them judicially.

 

The features in question are colloquially called “Friend Assemblies” and “Type Forwarders”. They have different names within the product, but I recommend using these names since they are accurate and easier for folks to grasp than InternalsVisibleTo and TypeForwardedTo. Learn more about them in the following posts in this series.

Tuesday, September 13, 2005 6:17:13 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |