February 2007 - Posts

While updating SQL Server 2005 to the SP2 level on my own machine and a server I maintain, I encountered the following problem:

  • Setup of Database Services and Analysis Services fails.
  • The error report mentions error 29528.
  • Description: "The setup has encountered an unexpected error while setting Internal Properties"

Solution: see KB925976. It worked for me on both machines. Running SP2 right now!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

I told you guys it was trivial :-). First of all, there's nothing wrong with the code:

1 class Weird 2 { 3 static void Main() 4 { 5 int i = 1; 6 for (i = 0; i < 100; i++) 7 { 8 System.Console.Write('.'); 9 } while (i <= 100); 10 } 11 }

Why? C# doesn't care about spacing; it could have written this as well:

1 class Weird { static void Main() { int i = 1; for (i = 0; i < 100; i++) { System.Console.Write('.'); } while (i <= 100); } }

Or - the more familiar form:

1 class Weird 2 { 3 static void Main() 4 { 5 int i = 1; 6 for (i = 0; i < 100; i++) 7 { 8 System.Console.Write('.'); 9 } 10 while (i <= 100); 11 } 12 }

The funny thing about it is the way it was created, but turning a do...while-loop into a for-loop without paying attention of the while portion. Actually, it had a totally different form which was a bit too heavy to put in here as a simple quiz. Originally, the loop termination condition was some boolean ok value that represents a test result of one single execution, do-whiling till the test fails at some random input - it was turned into a do-it-100-times kind of loop, so I ended up with some mixing of the following form:

bool ok; for (int i = 0; i < 100; i++) { //create some random input "someinput" ok = Foo(someinput); } while (ok);

This reflects the fact that both loop constructs have a totally different set of characteristics when it comes down to the use of loop condition variables and the overall structure. In this context, did you know there's a subtle difference between the two (wrong!) fragments below:

class Loops { static void Main() { for (int i = 0; i < 100; i++); { System.Console.Write("."); }; } }

class Loops { static void Main() { for (int i = 0; i < 100; i++);; { System.Console.Write("."); }; } }

The result? One dot on the screen. At compilation? One warning in fragment one, no warning in fragment two. This might better deserve the nominator "weird".

To conclude, I like Eber's summary of an "optical illusion" because that's exactly what it is. In this case, a kind of philosophical question is: "why is do...while (condition) terminated with a semicolon?" (as soon as the do part disappears, you end up with an infinite loop after all). Another typical optical illusion is this one:

1 int x = 18; 2 if (x > 16) 3 if (x > 18) 4 Console.WriteLine("More than 18"); 5 else 6 Console.WriteLine("Less than or equal to 16");

What will be printed on the screen? No rocket science, but coding style does matter!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Two hot releases today:


Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Some time ago I was giving a small lecture on .NET development talking about some CLR internals (largely based on SSCLI). During the talk on the JIT, the question of inlining popped up (does it happen?). This post shows inlining in action based on a little perf measurement. For more details, visit David Notario's blog for a few detailed posts on inlining. However, I was out of luck at the time of delivering the talk since I didn't have an internet connection (or more precise, only a crappy wireless one that wasn't to be called "reliable") so I had to come up with a sample on the fly. Luckily my temp folder (the one I keep all my demos in) contained a simple quicksort implementation that I used as a running example to illustrate some array stuff (unsafe code included), so I did instrument it with some Stopwatch stuff and a few large array sorting requests to see the impact.

The magic in the fragment below happens in the Swap function (one that C/C++ guys often would like to macro-ize or inline) - or better, when this particular function is called. Inlining basically means that the method call is eliminated and the code is put in place of the call (in a kind of "copy-paste" manner), which wipes out the overhead associated with the method call. In the managed world, this is something the JIT compiler can take care of. One limitation is that the method shouldn't be any larger than 32 bytes of IL, which is the case in our sample - so we're in luck.

1 using System; 2 using System.Diagnostics; 3 4 class Program 5 { 6 static Random rand = new Random(); 7 8 static void Main() 9 { 10 long ms = 0; 11 12 Stopwatch sw = new Stopwatch(); 13 for (int i = 0; i < 10; i++) 14 { 15 int[] array = GetArray(); 16 sw.Start(); 17 Qsort(array); 18 sw.Stop(); 19 ms += sw.Elapsed.Ticks; 20 } 21 22 Console.WriteLine(ms); 23 } 24 25 static int[] GetArray() 26 { 27 int[] array = new int[1000000]; 28 for (int i = 0; i < array.Length; i++) 29 array[i] = rand.Next(); 30 return array; 31 } 32 33 static void Qsort(int[] array) 34 { 35 Qsort(array, 0, array.Length - 1); 36 } 37 38 static void Swap(int[] array, int i, int j) 39 { 40 int t = array[i]; 41 array[i] = array[j]; 42 array[j] = t; 43 } 44 45 static void Qsort(int[] array, int from, int to) 46 { 47 if (from < to) 48 { 49 int b = from, e = to; 50 int p = array[b]; 51 52 while (b < e) 53 { 54 while ( array[e] > p) e--; 55 while (b < e && array[b] <= p) b++; 56 57 if (b < e) 58 Swap(array, b, e); 59 } 60 61 Swap(array, from, b); 62 Qsort(array, from, b - 1); 63 Qsort(array, b + 1, to); 64 } 65 } 66 }

Execute (release build) this piece of code and observe the execution time. (Note: The implementation above isn't the ideal quicksort implementation; use Array.Sort for "production" purposes, which is much better and more generic. One caveat in the code is on line 50 for the pivot choice - why?).

Next, change the code for the Swap-method as follows:

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] static void Swap(int[] array, int i, int j) { int t = array[i]; array[i] = array[j]; array[j] = t; }

and execute (release build) again. Observe the execution time now. On my machine the results are like this:

  • With inlining - 111631616 ticks
  • Without inlining - 130200309 ticks

So, yes, it matters (about 15% perf difference in this sample)! And even better ... you get it for free!

For the IL geeks, the latter code fragment produces the following IL:

1 .method private hidebysig static void Swap(int32[] 'array', 2 int32 i, 3 int32 j) cil managed noinlining 4 { 5 // Code size 16 (0x10) 6 .maxstack 4 7 .locals init (int32 V_0) 8 IL_0000: nop 9 IL_0001: ldarg.0 10 IL_0002: ldarg.1 11 IL_0003: ldelem.i4 12 IL_0004: stloc.0 13 IL_0005: ldarg.0 14 IL_0006: ldarg.1 15 IL_0007: ldarg.0 16 IL_0008: ldarg.2 17 IL_0009: ldelem.i4 18 IL_000a: stelem.i4 19 IL_000b: ldarg.0 20 IL_000c: ldarg.2 21 IL_000d: ldloc.0 22 IL_000e: stelem.i4 23 IL_000f: ret 24 } // end of method Program::Swap

Observe the noinlining implementation flag on line 3 which tells the JIT compiler not to inline the method. Needless to say, you could also ildasm /out the original .exe file, add noinlining and re-ilasm the IL code to an .exe file ("roundtripping") to illustrate the same instead of using MethodImplAttribute as shown above.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

A little tip but definitely a time-saver in case you didn't know about it yet... Quite a bit of Word users should be familiar with this one:

What I'm talking about is ALT+mouse selection (any official marketing name for this feature out there?). Guidelines: hold the ALT button on the keyboard and make a selection with the mouse; you'll be able to select a "rectangular block" of text. But did you know it's out there in Visual Studio too?

The reason for this post: recently a reader of my blog complained about the line numbering in my code samples:

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace RunspaceDemo 6 { 7 class Class1 8 { 9 public void Bar() 10 { 11 Console.WriteLine("Hi there"); 12 } 13 } 14 }

When copying this piece of code to Visual Studio, you'll see something like this:

Of course, you could manually delete all of the line numbers. However, using ALT+select this becomes much easier:

Just press Delete and you're ready to go!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Time for a new C# quiz - well, sort of. What does the following print on the screen and why (should be trivial)?

1 class Weird 2 { 3 static void Main() 4 { 5 int i = 1; 6 for (i = 0; i < 100; i++) 7 { 8 System.Console.Write('.'); 9 } while (i <= 100); 10 } 11 }

Have fun!

Why this quiz? While preparing another blog post I did quite some copy-paste and replace work, ending up with a similar construction as the one above (although it was less "visible" because of lots of code being commented out). (Tip: To set your mind, I started from a do...while loop and turned it into a for-loop, but I forgot to remove the while-part of the old loop construction, resulting in a somewhat special result.)

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Early Bird - 591x278

The Developer & IT Pro Days conference has become a yearly get together for lots of technology experts from both Developer and IT Pro audiences. So, I'm very happy to announce the 2007 edition on my blog too. Lots of great stuff is about to be covered out there, so don't miss out this opportunity. An overview:

  • The main conference will be held in Ghent (ICC) on March 28 and March 29.
  • !!!New!!! On March 27 there will be a preconference for the first time - AFAIK - in the history of Developer & IT Pro Days. There are two tracks:
    • MSDN - Jeff Prosise will talk about ASP.NET 2.0, ASP.NET AJAX and WPF/E - really recommended for web developers living on the cutting edge of technologies.
    • TechNet - IT Pro's will have the opportunity to see Ronald Beekelaar's talk on Virtualization technologies. Time to learn more about Virtual Server, System Center VMM, Longhorn Server's Hypervisor and more.
  • Registration is open with a 15% early bird discount till February 28th. The prices are outlined on the registration page.
  • A list of sessions can be found in the Agenda overview. There will be 7 parallel sessions (3 for MSDN + 3 for TechNet + one additional) each time slot, so plenty of choice. The agenda isn't complete yet, so check the website regularly for updates. Since we live in a multi-lingual country and lots of international speakers are coming here to speak, all sessions will be given in English.
    • Btw, I'm having the honor to present "Internet Information Services (IIS) 7.0: End-to-End Overview of Microsoft's New Web Application Server" in the MSDN track on March 28th in the late afternoon (agenda subject to change; precise details on the session and timing will follow later).


Developer & IT Pro Days 2007

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Dear blogging friends, I'm back from some blog silence due to other priorities during last weeks . Although it will take some time to get back up to speed in the blogosphere, I decided to leave you no longer hungry for some cool stuff and posted this simple warming-up sample of Windows PowerShell runspaces.


Runspaces in a few words

One of the coolest things about Windows PowerShell is the fact that the entire command line processor and pipeline infrastructure can be hosted by applications other than the PowerShell.exe executable itself. Basically, that's what the MMC 3.0 layering on top of Windows PowerShell is all about, which has been fully realized in the Exchange Server 2007 product. In this and upcoming posts I want to show you how you can leverage the power of all this magic in your own applications, allowing you to realize such a layering yourself: build cmdlets and host the PS engine!


A simple snap-in

In order to illustrate the use of a runspace, we need to create some snap-in first (or you could reuse an existing one). Please revisit my previous posts on Windows PowerShell for more information on the creation of cmdlets; in this post I'll assume you know what a cmdlet is and how you create a parameterized one. Below you can find the code for a snap-in containing two cmdlets which are rather self-explanatory:

using System; using System.Collections.Generic; using System.Text; using System.Management.Automation; using System.ComponentModel; namespace DemoSnapIn { [Cmdlet(VerbsCommon.Get, "Greeting")] public class SayHelloCmdlet : PSCmdlet { private string name; [Parameter(Mandatory = true, Position = 0)] public string Name { get { return name; } set { name = value; } } protected override void ProcessRecord() { this.WriteObject("Hello " + name); } } [Cmdlet(VerbsCommon.Get, "Permutations")] public class PermutationGeneratorCmdlet : PSCmdlet { private string _string; [Parameter(Mandatory = true, Position = 0)] public string String { get { return _string; } set { _string = value; } } protected override void ProcessRecord() { foreach (string s in GetPermutations(_string)) WriteObject(s); } static void Swap(StringBuilder sb, int i, int j) { char t = sb[i]; sb[i] = sb[j]; sb[j] = t; } static IEnumerable<string> GetPermutations(string s) { int len = s.Length; StringBuilder sb = new StringBuilder(len); sb.Append(s); return GetPermutations(sb, 0, len - 1); } static IEnumerable<string> GetPermutations(StringBuilder sb, int b, int e) { if (b == e) yield return sb.ToString(); else { for (int i = 0; i <= e - b; i++) { Swap(sb, b, b + i); foreach (string r in GetPermutations(sb, b + 1, e)) yield return r; Swap(sb, b + i, b); } } } } [RunInstaller(true)] public class MySnapIn : PSSnapIn { public override string Name { get { return "DemoSnapIn"; } } public override string Description { get { return "Sample snap-in"; } } public override string Vendor { get { return "Bart"; } } } }

Note: the permutation searcher is just a simple straightforward implementation to illustrate cmdlets that produce multiple results; please ignore the algorithm used which has a bit of a quick-n-dirty fashion :-)

Put the code above in a C# class library project, add a reference to System.Management.Automation (you might want to copy the System.Management.Automation.dll file from the GAC to some folder in order to reference it - recall the GAC can be found under %windir%\assembly\GAC_MSIL through the command-line); compile the whole thing (preferably with a strong name) and open up a VS2005 command-line (under Windows Vista launched using "Run as Administrator" in order to have the necessary privileges to write to the registry, a task executed by installutil.exe). In the command-prompt, navigate to the bin\Debug or bin\Release folder (according to the build type you chose) and execute installutil.exe -i DemoSnapIn.dll (assuming the assembly is named DemoSnapIn.dll of course):

Next, open Windows PowerShell and check whether the registration was successful by calling get-pssnapin -registered:

You should be able to call both the get-greetings and get-permutations cmdlets once you have added the snap-in to the shell:


Hosting a runspace

Time to call the cmdlets from inside another application. To illustrate this, create a new console application in C#, add a reference to System.Management.Automation (you might want to copy the System.Management.Automation.dll file from the GAC to some folder in order to reference it - recall the GAC can be found under %windir%\assembly\GAC_MSIL through the command-line). Next, add the following code:

using System; using System.Management.Automation.Runspaces; using System.Management.Automation; namespace DemoCmdHost { class Program { const string name = "Bart"; const string perm = "Abc"; static void Main(string[] args) { RunspaceConfiguration config = RunspaceConfiguration.Create(); PSSnapInException ex; config.AddPSSnapIn("DemoSnapIn", out ex); if (ex != null) throw ex; using (Runspace rs = RunspaceFactory.CreateRunspace(config)) { rs.Open(); Pipeline p = rs.CreatePipeline(); Command cmd = new Command("get-greeting"); cmd.Parameters.Add("Name", name); p.Commands.Add(cmd); Console.WriteLine(p.Invoke()[0].BaseObject as string); } using (Runspace rs = RunspaceFactory.CreateRunspace(config)) { rs.Open(); Pipeline p = rs.CreatePipeline(); Command cmd = new Command("get-permutations"); cmd.Parameters.Add("String", perm); p.Commands.Add(cmd); foreach (PSObject o in p.Invoke()) Console.WriteLine(o.BaseObject); } } } }

That's it! Here's the result you should get:

More will follow later. Take a look at the Windows SDK documentation for Windows PowerShell too.


Calling all Windows Vista users - Download Windows PowerShell now

Over here:

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

More Posts « Previous page