Monday, April 28, 2008

Calculating remaining time


It might sound strange, but one feature I really like in an application is the ability to estimate remaining time. Wheter it is the time it will take to install an application, copy a file or perform another lengthy process.

The last time I came across such an application was while installing TrueCrypt. It has a fantastic timer which updates itself continously during the installation.

Here is a method I wrote for Cosmos for determining how much time remains for compiling the operating system. The method takes two arguments, one for how far we've come in the process, and one for the total length of the process.

The major strength of this method is that it continously recalculates how much time remains. So no more "1 second remaining" for minutes, or grossely missing the target by estimating years to copy a single file.

public static System.Diagnostics.Stopwatch xBuildTimer;
public TimeSpan CalculateRemainingTime(int completedCount, int totalCount)
{
    if (xBuildTimer == null)
    {
        xBuildTimer = new System.Diagnostics.Stopwatch();
        xBuildTimer.Start();
    }
 
    long percentComplete = (completedCount * 100 / totalCount);
    if (percentComplete == 0) //Avoid Divide by Zero
        percentComplete = 1;
 
    long remaining = (xBuildTimer.ElapsedMilliseconds / percentComplete) 
        * (100 - percentComplete);
 
    return new TimeSpan(remaining * 10000);
}

Saturday, April 5, 2008

The joy of Extension Methods in C# 3.0

I discovered a new addition to C# 3.0 called Method Extension while I was writing a convertor for Hex and Binary for Cosmos today. Method Extension is a technique for "spot-welding" methods on to existing classes or types.


    //Without C# 3.0 Method Extension
    if (IsOdd(7))
        ;
 
    //With C# 3.0 Method Extension
    if (7.IsOdd())
        ;


Here the I've added the IsOdd method onto an integer type. I think the lower example is a lot easier to read than the upper.

Adding an extended method is as simple as adding 'this' keyword on the first parameter on a static method inside a static class, like this:


public static class IntExtender
    {
        /// 
        /// Checks if number is odd or even.
        /// 
        public static bool IsOdd(this int n)
        {
            if ((n % 2) > 0)
                return true;
            else
                return false;
        }
    }


Method Extensions requires a reference to System.Data.Core assembly in your project.


The Intellisense looks like this:














By adding extensions in Cosmos we can now directly convert numbers to Hex and Binary like this:

foreach (byte b in bytes)
    {
        Console.Write(b.ToBinary());
        Console.Write(b.ToHex());
    }