# Thursday, May 19, 2005

Some time ago, I moved my blog to a 64-bit X64 server. This server was running Windows Server 2003 SP1 Beta 1 and an early version of Whidbey Beta 2. I thought that this was an excellent opportunity to dogfood (MS term for early adoption) the 64-bit version of the framework, not to mention Server 2003 SP1. Another side aspect of this exercise was that I was testing out the backwards compatibility of the .NET Framework, since DasBlog is built with the v1.1 version of the Framework.

I'm happy to report that I've had zero problems with this new configuration, even with beta software. The OS has now shipped, so there is no issue there, but the version of Whidbey is still only Beta 2 and it is chugging day after day without issue. Doesn't get better than that! It also shows the incredible value of MSIL -- what C#, VB.Net, Eiffel, IronPython, Cobol and any other managed code compiler compiles down to -- given that the Everett DasBlog code "just works" on 64-bit Whidbey, even though 64-bit was not a supported (or possible) configuration of Everett.

One of the major features of Whidbey ASP.Net is XHTML compliance. DasBlog was not designed to be 100% XHTML compliant, so would not work on the first try on Whidbey. We had to use a special config switch to turn off XHTML compliance in Whidbey. After that, everything worked perfectly, in terms of performance, backwards compatibility and general behaviour of the app. I'm very happy and can say that Whidbey Beta 2 is ready for prime-time development. To that end, the .NET Framework is allowing companies to "go live" with our "go live" license. This means that you can build/migrate a public-facing application with Whidbey Beta 2.

Back to 64-bit ... I must say that the 64-bit support in Whidbey is very cool. I have two high-end X64 boxes in my office, one from Intel and the other from AMD. I use them for various purposes and am quite happy with them. In particular, I really like building and debugging apps on my 64-bit machines, having them run in native 64-bit, but then being able to deploy them to both 32- and 64-bit machines. The portability of managed code assemblies across different CPU architectures (IA64, X64, X86) is a huge win.

I've also been running early 64-bit versions of Longhorn on these two X64 machines. I haven't done any tests using >2GB of virtual address space, but I would like to see a managed app that does that, taking full advantage of the 64-bit address space. I can imagine that companies running SQL Server will immediately see the benefit of that removed barrier.

Thursday, May 19, 2005 8:35:01 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, May 12, 2005

Managed Debugging Assistants are an existing feature (Customer Debug Probes) improved on and expanded. They are exposed in a similar manner to exceptions (don't let that scare you) but occur not because of an error condition, but because the runtime has noticed a condition that could cause you problems. We've talked to lots of customers over the years and have received feedback that there are a set of scenarios that cause developers pain more often than others. As a result, we've written a bunch of code -- the MDAs themselves -- that can be used while your code is running to protect you against these pain points ... that's good, right?

The MDA infrastructure is always "on", but only a few MDAs are activated by default. That's easily changed, by selecting the "Debug" menu and "Exceptions" within it. From there, you can turn on or off any MDA of your choosing, as you can see in the image below. There is only one MDA turned on in that part of list in the image below, but you turn on as many as you want.

VS 2005 exceptions window

Anyway, I want to introduce you to the LoadFromContext MDA. If you want to know more about the joys of LoadFrom, check out Suzanne's blog. I'll post more on binding contexts at some point, but want to stay on the subject of this MDA for the moment. Here is some code that exercises this MDA -- this is just an exe project attempting to load a built assembly from a class library project in the same solution (hence the strange pathing) ...

using System;
using System.Reflection;

namespace LoadFromMDA
{
class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.LoadFrom(@"..\..\..\SomeAssembly\bin\debug\SomeAssembly.dll");
Console.WriteLine(asm.FullName);
}
}
}

If the MDA is enabled, I get the following exception-looking popup window as soon as hit the first line of code.

LoadFromContext MDA window

The reason that this MDA is so useful is that it is really quite difficult to determine for certain which binding context an assembly was loading into, other than following a certain set of rules and closely watching the way that the binder binds to dependent assemblies. However, with this MDA, you can know for sure if you are loading assemblies into the LoadFrom context.

There are several other MDAs to play with. I recommend taking a look through them and turning on ones that might apply to your program. There is no harm and you may avoid your program throwing an exception in some edge-case scenarios for reasons that may not be super clear to you.

 

Thursday, May 12, 2005 2:27:53 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, May 09, 2005

A few of us are heading to Phoenix in a week to visit companies and user groups interested in or currently deep into .NET Framework development. Our schedule is fully booked, but we can likely make some time still (there are three of us) if you are going to be in Phoenix during that time and would like to meet someone from the CLR team to talk about various aspects of .NET Framework development. Mail me if you are interested. There is also BetaDays happening on the thursday of that week. See Brad's post for more about that. Scott Guthrie, the Product Unit Manager of ASP.Net, will be at BetaDays and will be coming along with us to visit with one of the companies, which happens to be quite deep into ASP.Net-based development.

Brad also has an interesting post and links to many others about his Atlanta trip last week. It sounds like Brad, Kit, Claudio and Jason had an amazing time, at least judging from all the blog posts.

We're (the Phoenix tripsters) meeting the Atlanta tripsters later this afternoon for drinks to get some tips and feedback from their recent trip. It should be interesting to hear how everything worked out after a week of intense interaction with the Atlanta community. From the pics, it looks like everyone was having a lot of fun. 

There are a set of other trips still in the process of being booked. Please ping me if you've got some compelling reasons (bunch of companies using or wanting to use the .NET Framework, active usergroup(s), good restaurants)for us to come visit your city.

Phoenix, here we come!

Monday, May 09, 2005 2:51:42 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

Brad sent me mail on Friday night asking about our plans (or non-plans) to change the assembly version number again for Whidbey. The mail was the result of a developer -- let's call him Marc -- who had pinged Brad earlier in the week through his blog asking that exact question ...

Here is the basic question from Marc:

I'm using Beta 2 of the .NET Framework SDK 2.0 ... I'm curious, if I roll this app out, built on a beta ... Would the app continue to function or would it need to be rebuilt with the 2.0 final SDK?

There's too many exciting features to stick with the 1.x version of .NET. :-) Every day I find something new and exciting that can be done. It makes programming fun again!

I'm glad to hear that Marc likes Whidbey. That's definitely the plan from building 42 (where the CLR team works)! Back to the original question: will Marc's app continue to work or is a re-compile required? Marc isn't specific about which beta he is using, so I'm going to have to resort to a multi-part answer, unfortunately ...

1. If Marc is on Whidbey Beta 1 (or earlier), then the answer is "yes ... a recompilation is in your future".

2. If Marc is on Whidbey Beta 2 (or later), then the answer is "no ... your app should work just fine".

W/rt (2), I do recommend re-compiling against the final product even though it isn't strictly required (from a technical perspective). Naturally, there will have been further changes/fixes in the compilers and the metadata sub-system that will very likely result in a better built assembly.

Some of you might wonder what this is all about. I'll attempt to explain w/o going on any tangents. Please email if there are some tangents that you are interested in ;)

We set the assembly version number of each of the assemblies (all the same version fortunately) in the .NET Framework at major milestones, treating it as an contract between the .NET Framework and it's consumers. We then break that contract by changing the assembly version number again when we start a new milestone (i.e. Beta 1 versus Beta 2; Everett versus Whidbey). Why do we do that? We change the assembly version number for two reasons: (A) the contract has changed since the code inside the assemblies is very substantially different, and (B) a strong identifier (i.e. a version number) needs to be changed to remain a strong identifier.

We changed the assembly version number last early in the Beta 2 milestone, for the reasons described above. We will not change it again in the Whidbey product since the rate of changes to the product has slowed down and because we only want to make changes at this point that are absolutely required to ship the product.

As a result of how we've changed the assembly number and since the assembly binder binds strictly on the whole version number, apps built with Whidbey Beta 2 will continue to reference Whidbey RTM .NET Framework assemblies since their version number will be the same as what the Whidbey Beta 2 app is expecting.

Hope that helps Marc!

Monday, May 09, 2005 6:36:31 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, January 24, 2005

As you may guess/hope, we're doing our best to close down Whidbey Beta 2 ... so that we can ship it out to you to use. As part of that, we recently completed a security push to ensure that we are shipping a secure product. Another product axis that we also strive to deliver upon is compatibility. We have a set of processes and tools for ensuring that Whidbey is backwards compatible, to ensure that assemblies compiled against the v1.0 or v1.1 .NET Framework execute without issue on the v2.0 (Whidbey) .NET Framework.

You can help too, to ensure that we are delivering on compatibility in Whidbey. First, check out my colleague Jesse's posting @ GotDotNet that allows you to easily do compatibility testing against Whidbey Beta 1.

If you do find a problem, compatibility issue or otherwise, tell us about it @ the MSDN Product Feedback Center. We get this feedback delivered directly into our bug database and we deal with this feedback alongside the regular bugs that we get from our testing teams. Here is an example of a user-reported bug that we fixed that happened to be a compatibility-break.

I also plan to do a series on compatibility here to provide more transparent information on our compatibility bar and story.

One last thing ... here is our existing .NET Framework compatibility site. Jesse and I are planning on building a new site that is easier to use. I would have built it against Whidbey Beta 2, but he suggested that we build it against Everett/SQL 2000 and then host it on Whidbey/Yukon to dogfood Whidbey and Yukon compatibility. So, that's what we're doing. Cool, eh?

Monday, January 24, 2005 5:57:22 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [13]  | 
# Saturday, January 15, 2005

I decided to whip up a quick app today to test some behaviour of Assembly.LoadFrom() that I wasn't 100% certain about. In particular, I was curious about the dependency resolution behaviour of Assembly.LoadFrom(), as compared to Assembly.Load(). I know that Load() will find static dependencies for you, provided that the dependencies are in a place that the loader looks (i.e. GAC, appbase, private bin paths). I also know that Assembly.LoadFile() doesn't do any dependency resolution for you; you have to pre-load dependencies when you use LoadFile(). So, the test is to determine which camp -- dependency resolution or not -- that LoadFrom falls into. I'm pretty sure that it will fall into the dependency resolution camp, but I've never explicitly tested this case in issolation, so I'm checking it out. I've also written a bunch of apps that depended on LoadFrom resolving dependencies for you, so this likely isn't going to end up being a big surprise.

An Exercise in Reflection

So, I have to admit up front that I'm not great at using Reflection -- another bloke works on that. Anyway, I had to brush up on my reflection skills to get this working and ask Joel if I'd done it properly once I was done, which turned out to be mostly the case.

Here's the main program:

        static void Main(string[] args)
        {
            Assembly a;
            Type t;
            MethodInfo m;
            Object[] myArgs;
            Object myInt;

            Console.WriteLine(
"In main program");

            
//Loading assembly
            
//a = Assembly.LoadFile(@"C:\Documents and Settings\rlander\My Documents\Visual Studio 2005\Projects\LoadFromApp\FooLibrary\bin\debug\FooLibrary.dll");
            a
= Assembly.LoadFrom(@"../../../FooLibrary/bin/debug/FooLibrary.dll");

            
//Getting type to call into
            t
= a.GetType("FooLibrary.Foo");

            
//Getting the specific method that I'm interested in
            m
= t.GetMethod("GetInt", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(System.Int32)},null);

            
//args to pass to the method
            myArgs
= new Object[1] {5};
            
            
try
            {
                
//Calling the method and printing the return value
                myInt
= m.Invoke(null, myArgs);
                Console.WriteLine(myInt.ToString());
            }
                
//in case something bad happens
            
catch (TargetInvocationException e)
            {
                Console.WriteLine(e.InnerException.ToString());
            }
        }

Indeed, there is more to this program than just the Main method, however, the additional aspects are not particularly interesting. The code above is the whole of a Console exe project, called LoadFromApp, in VS 2005. There are two other projects that I wrote too: (1) a Class Library project called FooLibrary that the exe loads via Assembly.LoadFrom(), and (2) another Class Library project called BarLibrary to which FooLibrary statically links. You can see these too/two in the code sample, which is linked at the bottom of the entry.

The expected behaviour, now that you have a mental model of my project, is that BarLibrary is automatically loaded by the CLR loader when I load FooLibrary from LoadFromApp via Assembly.LoadFrom(). BarLibrary is necessarily in the same directory as FooLibrary; otherwise, there would be no way that LoadFrom() could find BarLibrary, unless BarLibrary was in the GAC or something like that. This is why VS adds referenced assemblies into your bin/debug (or release) folder when you build an assembly.

The interesting thing is that this exercise turned out to be more of a lesson in reflection than in the loader, but that's how these things end up. I'll tell you what I learned about LoadFrom and then reiterate what Joel told me about reflection.

What I Learned

First, the loader part. So, it does indeed turn out to be true that Assembly.LoadFrom() does resolve dependencies, provided that there are in a findable place, which turns out to be any place that would be consulted for Assembly.Load() and the path (minus filename.dll) of the Assembly.LoadFrom(String path). That wasn't too hard, but was worth the exercise.

You'll also notice that I commented out Assembly.LoadFile(), just above Assembly.LoadFrom(). I tried this too for kicks, which resulted in an exception of type System.Reflection.TargetInvocationException. That's the “something bad happens” and what the exception handler is for above. So, this proves that LoadFile() does not resolve depencies, which I already knew, but was a good test anyway.

Now, onto the reflection aspect. The comments in the source above mostly explain what is going on, I hope. If not, I load an assembly, get a known type from that assembly, then get a known method from that type and then call through on that method with known data. Do remember/realize that this isn’t normally what .net code looks like. Reflection is one of the mechanisms of handling late bound scenarios for .net coders. It is probably the most flexible, but not the most approachable.

Back to the interesting review of reflection … The line that I'm most interested in is the call to t.GetMethod, which is the instance method MethodInfo.GetMethod. I'll re-print it here:

            //Getting the specific method that I'm interested in
            m = t.GetMethod("GetInt", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(System.Int32)},null);

The GetMethod method allows you to specify enough information for the reflection system to get a single method for you from a given type. The thing is that you'll get some type of exception if you haven't specified enough information to single out your desired method from the set of methods on the type. Put another way, you’ll get this exception if the reflection system ends up finding >1 methods that fit your description since the method only returns MethodInfo, not MethodInfo[]. GetMethods() returns MethodInfo[] and obviously doesn’t have this particular problem. So, you need to be pretty specific about the method that you want. It may not be neccesary this version, but you may add overloads next version and forget that your GetMethod call was pretty sloppy and then stuff breaks, which is bad.

It is the first two and fourth parameters that are the most interesting to me. The first one is the method name. So, this differentiates the method from all other methods. You can make the search case insensitive via the BindingFlags, but I would not recommend this approach since the CLR doesn’t work this way and it will slow down the whole operation. The next parameter is the BindingFlags. I've stated that the method I'm looking for is static and public. So, the search will not retreive any instance or internal/protected/private methods that happen to have the same name, which is quite possible. You’ll need to pick among these flags carefully to ensure that you have the correct level of specificity. The fourth parameter specifies the signature of the method. Rememer, the CLR doesn't consider the return type when determining which overload of a method to call, so the signature is just the types of the parameters that the method takes. At this point, you will have provided enough data that the reflection system can narrow its search of methods on the given time to 1, or 0 if it is not there.

The actual code sample that I wrote is on another machine. I'll post it in a day or two when I get a chance. The sample is nothing big, but you'll be able to see how LoadFrom() and LoadFile() work for yourself with my small contrived example.

Saturday, January 15, 2005 5:10:21 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [3]  | 
# Friday, January 14, 2005

I'm currently working on some samples that showcase how best to use shadow copying, set private bin paths and load/use add-ins. I'll start posting these when I get the samples done and come up with a good story around them. My next post, which is almost done, is on Assembly.LoadFrom() and Reflection.

Anyway, I'm curious about what aspects of the CLR Loader and AppDomains that folks are most interested in/confused about. I've seen a bunch of posts on the microsoft.public.dotnet.framework.clr newsgroup that I'm using as a good sample of areas to post on -- hence my first post.

Friday, January 14, 2005 6:39:59 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [12]  | 
# Wednesday, December 15, 2004

I was reading the CLR newsgroup and noticed the following post about unhandled exceptions. I wasn't quite sure exactly how this worked, so I wrote a quick app that caught exceptions from other domains in the defaul domain. This behaviour was what the poster was looking for.

You can download the code [Everett | Whidbey ] to see how it works.

The basic idea is that you register for the AppDomain.UnhandledException event. This event will be fired for any exception that is not handled in any domain in the process. You cannot swallow the exception at this point, so your app will die no matter what. You can, however, do any cleanup that is required or put up some kind of user notification. In the case below, you can see that I tell the user that an unhandled exception occured. I'm sure that this is going to be quite useful to them ;)

Here is the bulk of the code:

    class Program
    {
        static void Main(string[] args)
        {

            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            AppDomain domain2 = AppDomain.CreateDomain("domain2");
            domain2.CreateInstance("DomainLib", "DomainLib.ThisClassThrows");

        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = (Exception)e.ExceptionObject;
            Console.WriteLine("Unhandled exception!!");
            Console.WriteLine(ex.InnerException.Message);
        }
    }

Another option, which is a good idea, is to use try/catch blocks in your code around calls to other domains. That way you can catch the exceptions that come across the domain boundary as opposed to just settle for process termination.

Wednesday, December 15, 2004 6:45:03 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [11]  |