• Hardware planning

    As my time at Viterra/ABB Grain is rapidly drawing to a close (more about that later), I've started to think about what would be useful (if not essential) for the next stage in my career (more about that later too!).

    I think a laptop might be a useful tool. For the last couple of CodeCampSA events, I've borrowed my Mum's Toshiba. It's quite a nice machine, but I don't think she'd be too keen on lending it to me all the time! I don't know much about various models, but if I could manage to fit an SSD into the budget then I hear that can make a big difference.

    For a while now I've also wanted to get up to speed with Hyper-V. The only thing preventing me has been access to suitable hardware. When Ben (the Virtual PC Guy) published the specs of the server he runs at home my eyes lit up, as it seems pretty similar to what I would like to achieve. Specifically

    • Hosting Windows Home Server
    • Running up VMs to run various server environments – particular different versions of SQL Server.

    Finally if there was any room left in the budget, I'd really like to upgrade my main desktop machine too – it must be a joy to develop on machine like Scott Hanselman's.

    Still, while my existing desktop is is an aging old box, it does the job and manages to run Windows 7 pretty well. One advantage of getting the Hyper-V server up and running would be that I could just RDP from my old box to a VM instead.

  • Two cool Christmas presents

    Christmas has always been a special time for me, and now it's also special for the kids too. This year my sister generously bought me a new car… Super Grover in his convertible car Pretty neat huh? Carson got given this electronic robot. Electronic robot It came as a kit, which meant I had to pull out my trusty old soldering iron and solder all the components onto the PCB then assembly all the gearbox bits. I seem to recall my success rate for soldering electronic kits wasn't very good, but I'm pleased to report I managed to get this one working first time. Probably a good thing as I would have no idea how to fix it if it hadn't worked! When you turn it on, it runs around the floor, and changes direction when the IR sensors detect an object in the way. Merry Christmas and a Happy New Year to everyone.

  • Watching the .NET Garbage Collector

    Here's an interesting use of SciTech's .NET Memory Profiler – watching how objects are handled by the .NET CLR garbage collector.

    The sample code create 4 objects – a simple class "Simple", a class that implements IDisposable "Disposable", and a class that also implements a destructor "Destructable".

    .NET Memory Profiler can generate a real-time graph of memory allocations. I've instrumented the sample code using SciTech's API to add comments to the graph so you can match the code execution path against the X axis (time). The object instance count is mapped to the Y axis.

    image

    See how 2 instances of the "Destructable" class existed around the 10 second mark – then one was released at the first GC, then the 2nd (which has the destructor) is only released after the 2nd GC.

    using System; using System.Diagnostics; using SciTech.NetMemProfiler;

    namespace MemoryTesting { internal class Program { private static void Main(string[] args) { MemProfiler.FullSnapShot("Start");

            CreateSimple();
    
            CreateDisposable();
            System.Threading.Thread.Sleep(1000);
    
            CreateDestructableAndDispose();
            System.Threading.Thread.Sleep(1000);
    
            CreateDestructable();
            System.Threading.Thread.Sleep(1000);
    
            MemProfiler.AddRealTimeComment("GC");
            GC.Collect();
    
            System.Threading.Thread.Sleep(2000);
            MemProfiler.AddRealTimeComment("WaitForPendingFinalizers");
            GC.WaitForPendingFinalizers();
    
            System.Threading.Thread.Sleep(2000);
    
            MemProfiler.AddRealTimeComment("GC");
            GC.Collect();
    
            System.Threading.Thread.Sleep(1000);
    
            MemProfiler.AddRealTimeComment("End");
            MemProfiler.FullSnapShot();
    
        }
    
        private static void CreateSimple()
        {
            MemProfiler.AddRealTimeComment("Create Simple");
    
            var a = new Simple();
            a.Something += OnEventHandler;
            a.Data = "hey";
    
            a.Something -= OnEventHandler;
    
        }
    
        private static void CreateDisposable()
        {
            MemProfiler.AddRealTimeComment("Create Disposable");
    
            var a = new Disposable();
            a.Something += OnEventHandler;
            a.Data = "ho";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;
    
            a.Dispose();
        }
    
        private static void CreateDestructableAndDispose()
        {
            MemProfiler.AddRealTimeComment("Create Destructable and Dispose");
    
            var a = new Destructable();
            a.Something += OnEventHandler;
            a.Data = "haha";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;
    
            a.Dispose();
        }
    
        private static void CreateDestructable()
        {
            MemProfiler.AddRealTimeComment("Create Destructable");
    
            var a = new Destructable();
            a.Something += OnEventHandler;
            a.Data = "haha";
            System.Threading.Thread.Sleep(1000);
            a.Something -= OnEventHandler;
            //a.Dispose();
        }
    
        private static void OnEventHandler(object sender, EventArgs e)
        {
            Debug.WriteLine("Something Fired");
        }
    }
    
    public class Simple
    {
        private string \_data;
    
        public string Data
        {
            get { return \_data; }
            set
            {
                \_data = value;
                OnSomething(null);
            }
        }
    
        public event EventHandler Something;
    
        protected virtual void OnSomething(EventArgs e)
        {
            EventHandler handler = Something;
            if (handler != null) handler(this, e);
        }
    }
    
    public class Disposable : Simple, IDisposable
    {
        #region IDisposable Members
    
        public void Dispose()
        {
            System.Threading.Thread.Sleep(1000);
    
            MemProfiler.AddRealTimeComment("Dispose");
    
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        #endregion
    
        protected virtual void Dispose(bool disposing)
        {
        }
    }
    
    public class Destructable : Disposable
    {
        ~Destructable()
        {
            System.Threading.Thread.Sleep(1000);
    
            MemProfiler.AddRealTimeComment("Destructing");
    
            Dispose(false);
        }
    } }