Working with Tasks in .NET Framework 4.0 - An Insight

The .Net framework 4.0 version is mounted with lots of new features, out of which the Parallel Programming using the Task Parallel Library (TPL) is the one gaining more interest. In this article I will write about the Task class under the namespace System.Threading.Tasks. The asynchronous operations scheduled through a Task class make sure that the system resources are used intelligently, such as scheduling the threads on different cores available on the processor; it also provides a lot of control over the scheduled tasks, like fetching the return value, cancelling a task, building nested tasks, etc.

Starting a Parallel Task

In this section let us see the various ways of starting the tasks. A Task class can be directly instantiated and started like that of a Thread class. Below is the sample code.

    static void Main(string[] args)
    {
        Task task1 = new Task(PrintA5Times);
        task1.Start();
        Console.ReadLine();
    }

In the above code a task is created when Task class is instantiated and only gets scheduled when the Start method is called. A task scheduler takes care of loading these tasks onto different threads. There is a factory class available, which can be used to create the task and schedule it instantly.

    static void Main(string[] args)
    {
        Task.Factory.StartNew(() =>
            {
                Console.WriteLine("This task is created and scheduled through task factory!");
            });
 
        Console.ReadLine();
    }

Synchronizing Tasks

When dealing with asynchronous operations, the most important thing is to know about the synchronization techniques. Below are the different ways to synchronize tasks.

Wait

Wait is an instance method available in the Task object. Calling this method only blocks the actual task until the task is completed or until a specified timeout.

    static void Main(string[] args)
    {
        Task task1 = new Task(PrintA1000Times);
        task1.Start();
        Task task2 = new Task(PrintB500Times);
        task2.Start();
 
        //Perform other operations
            
        //Wait for task1 to complete
        task1.Wait();
        Console.WriteLine("Task1 completed!");
 
        //Perform some more operations
 
        //Wait for task2 to complete with a time out
        task2.Wait(10000);
        if(task2.IsCompleted)
            Console.WriteLine("Task2 completed!");
        else
            Console.WriteLine("Task2 Timed out!");
 
        Console.ReadLine();
    }

WaitAll

WaitAll is a static method in the Task class and it can be used to synchronize all of the tasks. This method call will make the execution wait until all of the scheduled tasks are completed.

    static void Main(string[] args)
    {
        Task task1 = new Task(PrintA1000Times);
        task1.Start();
        Task task2 = new Task(PrintB500Times);
        task2.Start();
        Task task3 = new Task(SleepFor1Min);
        task3.Start();
 
        Task.WaitAll(task1, task2, task3);
        Console.WriteLine("All the tasks completed!");
 
        Console.ReadLine();
    }

WaitAny

This is again a static method in the Task class and it makes the execution wait until any one of the task is completed.

    static void Main(string[] args)
    {
        Task task1 = new Task(SleepFor3Min);
        task1.Start();
        Task task2 = new Task(SleepFor2Min);
        task2.Start();
        Task task3 = new Task(SleepFor1Min);
        task3.Start();
 
        int taskIndex = Task.WaitAny(task1, task2, task3);
        Console.WriteLine("Task with index {0} is completed", taskIndex);
 
        Console.ReadLine();
    }

Dependent Tasks

You can also create dependent Tasks by either attaching the child task to a parent task or by specifying a task to be scheduled only when the dependent task operation is completed.

ContinueWith

The ContinueWith method creates a new task and schedules it once the dependent task is completed. Below is the example demonstrating it.

    static void Main(string[] args)
    {
        Task<int> task1 = new Task<int>(GetTotal);
        task1.Start();
        Task task2 = task1.ContinueWith(task => PrintTotal(task.Result));
 
        Console.ReadLine();
    }

AttachToParent

This attaches the child task to the parent so a Wait method call on the parent task will be released only if the child task is completed. Below is an example.

    static void Main(string[] args)
    {
        Task task1 = Task.Factory.StartNew(() =>
            {
                PrintA10Times();
                Task task2 = new Task(SleepFor1Min, TaskCreationOptions.AttachedToParent);
                task2.Start();
            });
 
        task1.Wait();
        Console.WriteLine("Both parent and child tasks are completed!");
 
        Console.ReadLine();
    }

Cancellation of Tasks

In this section let us look at an example where a task can be cancelled. The basic idea is to pass the token value from the CancellationTokenSource object to the Task while creating it and when the Cancel method of the TokenSource is called, the corresponding Task is cancelled.

    static void Main(string[] args)
    {
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        Task task1 = new Task(SleepFor2Min, tokenSource.Token);
 
        //Wait for some time
        task1.Wait(1000);
        //Cancel the task
        tokenSource.Cancel();
 
        Console.WriteLine("Status of task1: {0}", task1.Status);
 
        
        Console.ReadLine();
    }

There many more things that you can accomplish using the Task class that the .net framework 4.0 has provided as a part of Task Parallel Library. With this insight on tasks I leave it to the user to explore more.

Happy reading!



Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Corporate e-Learning technology has a long and diverse pedigree. As far back as the 1980s, companies were adopting computer-based training to supplement traditional classroom activities. More recently, rich web-based applications have added streaming audio and video, real-time collaboration and other new tools to the e-Learning mix. At the same time, the growing availability of informal learning tools--a category that includes everything from web searches to social media posts--are having a major impact on …

  • With 81% of employees using their phones at work, companies have stopped asking: "Is corporate data leaking from personal devices?" and started asking: "How do we effectively prevent corporate data from leaking from personal devices?" The answer has not been simple. ZixOne raises the bar on BYOD security by not allowing email data to reside on the device. In addition, Zix allows employees to maintain complete control of their personal device, therefore satisfying privacy demands of valued employees and the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds