ReBuildAll Blog
Thoughts (mostly) on .NET development

Silverlight 3 designer (preview only) in Visual Studio 2008   (ASP.NET)   
I have encountered at least one person and read from one book, that Silverlight 3 does not provide a visual designer in Visual Studio 2008. Silverlight 2 had a preview only "designer", that would show the changes you made to the XAML in real time. The person/book suggested this would have been gone with Silverlight 3.

This is of course not true. Although a carefully hidden feature, it is very easy to enable it. After that you are not required to build and run your Silverlight application to see a preview of it.

Here is what VS 2008 looks like after you installed the Silverlight 3 tools:

a picture in a bl0g

I would like to call your attention to the very bottom, where you can see double lines. I drew a red rectangle there in the image above. When you move your mouse very carefully there, it will switch into a splitter cursor. Sometimes it will just flash for a second, but move your mouse very gently, and you can find it there (it is probably only 1 pixel thick, so accelerated mouse might have problem finding it).

Now click and drag, and voila!

a picture in a bl0g

Now simply click resume loading the designer. And you now have your full XAML preview only designer. You can zoom in and out and check out how your XAML page/control will look like.

While you cannot use it to actually drag and drop controls, it still saves a lot of time when you do not need to compile and run to see the end results.

a picture in a bl0g


ASP.NET MVC 2 released   (ASP.NET)   
ASP.NET MVC 2 was released today. More details in ScottGu's blog:

ASP.NET MVC 2 Released

TechDays 2010 Finland presentation slides (Finnish Only)   (Debugging)   
Below you can find the slides to my presentation "Web-sovellusten liikenteen debuggaus ja testaus" that I gave at TechDays 2010. They are only available in Finnish. You can also optionally download the demo web application that was used to demonstrate different scenarios with Fiddler. The ZIP archive contains also the SQL script and some simple setup instructions (the latter only in Finnish as well).

Web sovellusten liikenteen debuggaus (PowerPoint)
Demos

You can find Fiddler here:

Fiddler

(The presentation was about Fiddler, the English title could have been: Debugging and testing web-application traffic)

How to run a .NET application as a 32bit process in a 64bit OS   (Framework)   
When you compile a .NET program into an assembly and do not specify a CPU architecture, it will of course run on every architecture. It will also mean, that it will be run as a 32bit program on a 32bit OS (x86), and will be run as a 64bit program on a 64bit OS (x64).

Sometimes, you will want to force a .NET program to run as a 32bit application, even on a 64bit system. You might wonder, what on earth can make you do that. Well, here are two scenarios.

#1: The .NET program works on 32bit OS and crashes on 64bit

I have actually faced this scenario some while ago. As it turned out, the program did a p/invoke and that crashed on 64bit OSes. This was of course a bug on the part of the program, but I would not wait for the author to fix it. I needed to run the program as a 32bit application (on my 64bit OS), which would solve this issue.

#2: WinDbg will not handle stack frames in the call stack the same on 64bit and 32bit

This might or might not be a problem for you, and it might be solved in a later version of the Debugging Tools for Windows.

Solution: corflags.exe

To solve these problems you can use corflags.exe. This is included with the .NET Framework SDK. It can run without the SDK, so you can copy&paste it onto the target machine if you have to. With this tool you can change a flag value in the CLR header that will instruct the CLR to ALWAYS run the given application in 32bit mode. Clearing this flag will of course always run in the native mode of the OS.

To force 32bit mode on an application, use:

corflags assembly /32bit+

To not force 32bit mode and run in the native mode of the OS, use:

corflags assembly /32bit-

Running .NET threads on selected processor cores   (Framework)   
Today multi-threading is very popular. Just look at the upcoming .NET 4, with parallel programming built right into the framework. It is very easy to run a for or foreach loop that will utilize all cores in the machines - 2, 4, 8 -, and thus increasing performance.

But what if you want to restrict a thread to a given core yourself?

Process affinity

For the entire process, you can adjust the affinity - that is, the processor the process is allowed to run on - by using the following .NET code (C#):

            Process.GetCurrentProcess ().ProcessorAffinity = new IntPtr ( 2 );

This will restrict the current process to running on processor #2 (if we begin numbering with 1). The passed IntPtr is a bit mask, where the first bit means the first processor core, the second bit the second processor core, and so on. To run the process on all cores on a dual core system, you would use 3. On a quad core machine you would use 15.

The same scheme is in use if you have multiple processors. In that case starting from the first bit comes the cores for the first processor, then for the second processor, and so on. For a dual cpu system with dual cores, you would use 3 for the first cpu (both cores) and 12 for the second cpu (both cores).

Thread affinity

For threads, this is not so easy to acomplish. First of all, a .NET thread does not correspond to an operating system thread. And you can set thread affinity for OS threads only. Not only is there no correspondance, but the .NET Framework is allowed to run your .NET thread on multiple operating system threads. Not at the same time, but should your thread run long enough (waiting in between, etc), there is no guarantee that it will always run on the same OS thread.

To solve the problem of the CLR running .NET threads on multiple OS threads, you can use a method from the Thread class:

Thread.BeginThreadAffinity ();
...
Thread.EndThreadAffinity ();

This will guarantee that any code between these calls will always run on the same OS thread. Essentially this disables parts of the CLR thread management.

After we have this problem solved, we can get on with the thread processor affinity issue. You can get the OS threads in your .NET application by using Process.GetCurrentProcess ().Threads. This is a collection of thread objects. However, these are using OS thread IDs and not managed thread IDs. To get the currently executing OS thread, we can use P/Invoke to invoke the neccessary Win32 API code:

        [DllImport ( "kernel32.dll" )]
        public static extern int GetCurrentThreadId ();

With the returned ID we can find our thread, and the .NET ProcessThread object has a property called ProcessorAffinity. This property only has a setter, so you cannot get its value. The actual property works similar to the process affinity I described above.

Putting it all together

Now that we have pieces of the puzzle, it is time to put it together. Below you will find a complete class which I called DistributedThread that allows you to run threads on processor cores you can determine.

Before you start hard coding processor and core numbers, make sure you retrieve the available cores in the system (including all CPUs and cores) with Environment.ProcessorCount.

The code encapsulates the normal Thread object. It handles restricting the thread to run on the current OS thread and then setting the thread affinity to the desired value.

(if you wonder how you can get the code without the nice syntax highlighting, just request the page source, you will find it there ... a little challenge for you :P)

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;

namespace DistributedWorkManager
{
    public class DistributedThread
    {
        [DllImport ( "kernel32.dll" )]
        public static extern int GetCurrentThreadId ();

        [DllImport ( "kernel32.dll" )]
        public static extern int GetCurrentProcessorNumber ();

        private ThreadStart threadStart;

        private ParameterizedThreadStart parameterizedThreadStart;

        private Thread thread;

        public int ProcessorAffinity { get; set; }

        public Thread ManagedThread
        {
            get
            {
                return thread;
            }
        }

        private DistributedThread ()
        {
            thread = new Thread ( DistributedThreadStart );
        }

        public DistributedThread ( ThreadStart threadStart )
            : this ()
        {
            this.threadStart = threadStart;
        }

        public DistributedThread ( ParameterizedThreadStart threadStart )
            : this ()
        {
            this.parameterizedThreadStart = threadStart;
        }

        public void Start ()
        {
            if ( this.threadStart == null ) throw new InvalidOperationException ();

            thread.Start ( null );
        }

        public void Start ( object parameter )
        {
            if ( this.parameterizedThreadStart == null ) throw new InvalidOperationException ();

            thread.Start ( parameter );
        }

        private void DistributedThreadStart ( object parameter )
        {
            try
            {
                // fix to OS thread
                Thread.BeginThreadAffinity ();

                // set affinity
                if ( ProcessorAffinity != 0 )
                {
                    CurrentThread.ProcessorAffinity = new IntPtr ( ProcessorAffinity );
                }

                // call real thread
                if ( this.threadStart != null )
                {
                    this.threadStart ();
                }
                else if ( this.parameterizedThreadStart != null )
                {
                    this.parameterizedThreadStart ( parameter );
                }
                else
                {
                    throw new InvalidOperationException ();
                }
            }
            finally
            {
                // reset affinity
                CurrentThread.ProcessorAffinity = new IntPtr ( 0xFFFF );
                Thread.EndThreadAffinity ();
            }
        }

        private ProcessThread CurrentThread
        {
            get
            {
                int id = GetCurrentThreadId ();
                return
                    (from ProcessThread th in Process.GetCurrentProcess ().Threads
                     where th.Id == id
                     select th).Single ();
            }
        }
    }
}


How you can use this code?

   DistributedThread thread = new DistributedThread( ThreadProc );
   thread.ProcessorAffinity = 2;
   thread.ManagedThread.Name = "ThreadOnCPU2";
   thread.Start ();

As you can see the syntax is fairly similar to when you use Thread. The ManagedThread property gives access to the actual Thread object, should you need that. The affinity here is a single int value - the class handles converting that to IntPtr.

The PlayStation leap year of 2010   (CubeHead)   
I read yesterday about a problem with some of the Sony PlayStation 3 consoles. While I am not affected - having no such console in my possession - I was wondering what caused it. Today, I also read the explanation of what caused the problem. From the PlayStation blog:

We are aware that the internal clock functionality in the PS3 units other than the slim model, recognized the year 2010 as a leap year. ...

Now I wonder how on earth can something like this bug be programmed? I mean the algorithm is pretty straight forward. Even if you neglect to take the exceptions into account, recognizing 2010 as a leap year seems like ... well ... stupid?

The rule is BTW, if year evenly dividable by 4, its a leap year, except if dividable by 100, when its not, except if dividable by 400, when it still is. I remember it very well, because we have coded that in first year of university :) It was even used to demonstrate the ?: operator of the C programming language.

Anyhow, neither 10 nor 2010 satisfies this of course, and this is not a really hard algorithm. Even if you overlook the 100 and 400 rules, I simply cannot imagine how can you code this wrong? Any ideas? :)

(Actually what is even worse than the existence of this bug is the following. Because the PS3 Slim was not affected, obviously someone fixed this error later on, and still earlier models were not updated! Or maybe they just replaced parts - either software or hardware - with new ones in the Slim model, and those were already working? Who knows ...)