[C#] Multithreading in C# 4 [3] – Task Parallelism

You might have used “System.Threading.Thread” class without big troubles. I think the design of the “Thread” class is very traditional. If you have worked with multithreaded application for a while, you do not have any problems to understand how the “Thread” class works. But, admittedly, it is somehow technical and not intuitive, which makes the code error-prone.

1. What’s New to C# 4

In C# 4, the “System.Threading.Tasks.Task” class replaces the “System.Threading.Thread” class. MS did not deprecate the “Thread” class but it is now recommended to prefer “Task” to “Thread“.

The “Task” class and its supporting classes abstract some technical intricacies of “Thread” and provide more intuitive APIs.

Rather than creating a thread by yourself or dealing with a thread pool directly, you will make use of a thread pool indirectly with the “Task” class.

2. Task Class

There are 2 versions of Task class: Task and Task<T>

  • Task: when there is no return value
  • Task<T>: when there is a return value.

Task uses “Action” delegates, meanwhile Task uses “Func” delegates.

Task class provides the following properties to check the current task information:

public class Task : IAsyncResult, IDisposable
{
  public Object AsyncState { get; }
  public static Nullable CurrentId { get; }
  public int Id { get; }
  public bool IsCanceled { get; }
  public bool IsCompleted { get; }
  public bool IsFaulted { get; }
  public TaskStatus Status { get; }

  public TaskCreationOptions CreationOptions { get; }
  public AggregateException Exception { get; }
}

public class Task<TResult> : Task { }

You can check the “Status” property for the current status of a task, but you can check the most frequently used statuses with separate properties such as “IsCanceled” or “IsCompleted“.

3. Task Factory

When you work with “Task“, you do not generally create a task object directly. Through the static “Factory” property, you can get the “TaskFactory” object.

public class Task : IAsyncResult, IDisposable
{
  public static TaskFactory Factory { get; }
}

public class Task<TResult> : Task
{
  public static TaskFactory<TResult> Factory { get; }
}

The “TaskFactory” has the following 3 sets of methods with many overloaded versions:

  • StartNew
  • ContinueWhenAll
  • ContinueWhenAny
public class TaskFactory
{
  public Task StartNew(Action action); // Creates and starts a Task

  public Task ContinueWhenAll(Task[] tasks, Action continuationAction); // Creates a continuation Task that will be started upon the completion of a set of provided Tasks.

  public Task ContinueWhenAny(Task[] tasks, Action continuationAction); // Creates a continuation Task that will be started upon the completion of any Task in the provided set.
}

public class TaskFactory
{
  public Task StartNew(Func function);
  public Task ContinueWhenAll(Task[] tasks, Func continuationFunction);
  public Task ContinueWhenAny(Task[] tasks, Func continuationFunction);
}

4. Waiting for a Task to Complete

In C# 3, you used the “Thread.Join()” method to wait until a thread exits.

Task provides the “Wait()” method. (“Wait” seems a better name than “Join“.)

public class Task
{
  public void Wait();
  public static void WaitAll(params Task[] tasks);
  public static int WaitAny(params Task[] tasks);
}

5. Using Tasks

Let’s create a very simple example.

 public static void Test1()
{
  Task thread =
    Task.Factory.StartNew(() =>
      {
        Thread.Sleep(2000);
        Console.WriteLine("Doing some tasks: {0}",
          Thread.CurrentThread.ManagedThreadId);
      }
    );

  Console.WriteLine("Task {0} is {1}", thread.Id, thread.Status.ToString());
  Thread.Sleep(1000);
  Console.WriteLine("Task {0} is {1}", thread.Id, thread.Status.ToString());

  thread.Wait();
  Console.WriteLine("Task {0} is {1}", thread.Id, thread.Status.ToString());
}

Note that you do not need to call the “Start()” method explicitly.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s