June 30, 2013

Code Contract


This is a code contract type class that can make code assertions without throwing an Assert dialog during an NUnit test:
public static class CodeContract
{
    private static bool runningFromNUnit = false;

    static CodeContract()
    {
        runningFromNUnit = AppDomain.CurrentDomain.GetAssemblies().Any(a => 
               a.FullName.ToLowerInvariant().StartsWith("nunit.framework"));
    }

    private static bool IsRunningFromNUnit
    {
        get { return runningFromNUnit; }
    }

    private static bool UseAssert()
    {
        return ForceAssertOnError ||
            (Debugger.IsAttached && !IsRunningFromNUnit);
    }

    public static bool ForceAssertOnError
    {
        get;
        set;
    }

    public static void Requires(bool condition,
            string message = "", string extraInfo = "")
    {
        if (!condition)
        {
            string failType = "Contract requirement failure detected: ";
            Trace.TraceError(failType + message + extraInfo);
            if (UseAssert())
            {
                Debug.Assert(false, failType + message, extraInfo);
            }
        }
    }

    public static void RequiresArgument(bool condition, string paramName,
            string extraInfo = "")
    {
        if (!condition)
        {
            string failType = "Argument requirement failure detected: ";
            Trace.TraceError(failType + paramName + extraInfo);
            if (UseAssert())
            {
                Debug.Assert(false, failType + paramName, extraInfo);
            }
            throw new ArgumentException(extraInfo, paramName);
        }
    }

    public static void RequiresArgumentNotNull(object parameter, string paramName,
        string extraInfo = "")
    {
        if (parameter == null)
        {
            string failType = "Argument not null requirement failure detected: ";
            Trace.TraceError(failType + paramName + extraInfo);
            if (UseAssert())
            {
                Debug.Assert(false, failType + paramName, extraInfo);
            }
            throw new ArgumentNullException(extraInfo, paramName);
        }
    }

}

C# Task Object

Task basics
Task and Thread Difference

Here are some notes that I made from these and other blogs:
Task - Specifies some work to be executed asynchronously
ContinueWith - Specifies some work to be executed asynchronously after a task has completed

In computer science terms, a Task is a future or a promise. Basically, a Task "promises" to return you a T, but not immediately

A Thread is one of many ways to fulfill that promise. But not every Task needs a Thread. If the value you are waiting for comes from the filesystem or a database or the network, then there is no need for a thread. The Task might just register a callback to receive the value when the disk is done seeking.

In particular, the Task does not say why it is that it takes such a long time to return the value. It might be that it takes a long time to compute, or it might that it takes a long time to fetch. Only in the former case would you use a Thread to run a Task. (In .NET, threads are freaking expensive, so you generally want to avoid them as much as possible and really only use them if you want to run multiple heavy computations on multiple CPUs.

Tasks can be organised in parent child relationships so that a parent task will wait for its children to complete.

Here is an example of how to start a task with a particular return type and then wait for it to finish
var someTask = Task<int>.Factory.StartNew(() => slowFunc(1, 2));
Task<int32> task = new Task<int32>(n => Sum((Int32)n), 1000);
task.Start(); // Start the task
task.Wait();  // Wait for it to finish
Here is an example of how to cancel a task.
CancellationTokenSource cts = new CancellationTokenSource();
Task<int32> t = new Task<int32>(() => Sum(cts.Token, 1000), cts.Token);
t.Start(); // Start the task
cts.Cancel(); // Cancel the task

Task<int32> t = new Task<int32>(n => Sum((Int32)n), 1000);
       t.Start();
       // notice the use of the Result property
       Task cwt = t.ContinueWith(task => Console.WriteLine(
                       "The sum is: " + task.Result));
They are very easy to use and have a lot of advantages over Threads as follows:
  • You can create return types to Tasks as if they are functions.
  • You can the "ContinueWith" method, which will wait for the previous task and then start the execution. (Abstracting wait)
  • You can use Task.WaitAll and pass an array of tasks so you can wait till all tasks are complete.
  • You can attach task to the parent task, thus you can decide whether the parent or the child will exist first.
  • You can achieve data parallelism with LINQ queries.
  • You can create parallel for and foreach loops
  • Very easy to handle exceptions with tasks.
  • Most important thing is if the same code is run on single core machine it will just act as a single process without any overhead of threads.
Disadvantage of tasks over threads:
  • Not knowing what thread the task is invoked on can be a problem in itself when locking access to data so assume the worst.
  • You need .Net 4.0
  • Newcomers who have learned operating systems can understand threads better.

Tip:- Always use Task.Factory.StartNew method which is semantically perfect and standard. Actually, under the hood it is a slightly more efficient means to initiate the task as well.

Also can force a task to execute on the GUI thread:
// Get the UI thread's context
var context = TaskScheduler.FromCurrentSynchronizationContext();
...
Task task = Task.Factory.StartNew( () =>
   {
       // Do some work...           
   })
   // Continue on the UI thread, since this lets us update when our
   // "work" completes.
   .ContinueWith(_ => this.label1.Text = "Task Complete!", context);
OR even simpler from within the GUI do
Task task = Task.Factory.StartNew( () =>
   {
       // Do some work...           
   })
   // Continue on the UI thread, since this lets us update when our
   // "work" completes.
   .ContinueWith(_ => this.label1.Text = "Task Complete!",
       TaskScheduler.FromCurrentSynchronizationContext());