[C#] Multithreading in C# 4 [4] – Using Tasks

Task and Task<T> represents a multithreaded task. It has many options to use. In this post, let’s focus on how to start a task run it.

1. Passing Data to a Task

StartNew() methods will accept a delegate with parameters.

public class TaskFactory
{
  public Task StartNew(Action<Object> action, Object state);
}
public class TaskFactory<TResult>
{
  public Task<TResult> StartNew(Func<Object, TResult> function, Object state);
}

The following example passes the “Point2D” object to the task.

public class Point2D
{
  public int X { get; set; }
  public int Y { get; set; }
}

public static class TaskTest
{
  public static void Test1()
  {
    Task t = Task.Factory.StartNew(obj => // Point2D input
      {
        Point2D p = obj as Point2D;
        Thread.Sleep(2000);
        Console.WriteLine("{0}, {1}", p.X, p.Y);
      },
      new Point2D { X = 10, Y = 20 }
    );

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

2. Returning a Result from a Task

By using “Task<T>”, you can get the result from a task. To retrieve a result from a task, the “Task<T>” class provides the “Result” property.

public class TaskFactory<TResult>
{
  public TResult Result { get; internal set; }
}

Let’s modify the first example to return the modified object.

Task<Point2D> t
  = Task.Factory.StartNew( obj =>
    {
      Point2D p = obj as Point2D;
      Point2D p1 = new Point2D { X = p.X + 1, Y = p.Y + 1 };
      Thread.Sleep(2000);
      return p1;
    },
    new Point2D { X = 10, Y = 20 }
  );

t.Wait();
Console.WriteLine("{0}, {1}", t.Result.X, t.Result.Y);

Note that the result is strongly typed.

3. Chaining Tasks

Task” and “Task<T>” have the “ContinueWith” method to chain the tasks.

public class Task
{
  public Task ContinueWith(Action continuationAction);
}
public class Task<T>
{
  public Task ContinueWith<T>(Action<T> continuationAction);
  public Task<T> ContinueWith<T>(Func<Task, T> continuationFunction);
}

The following examples shows how to chain 2 tasks in a row.

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

  Task second =
    first.ContinueWith((t) =>
      {
        Console.WriteLine("Task 2 - How about the first task: {0} - {1}", t.Id, t.Status.ToString());
        Thread.Sleep(2000);
        Console.WriteLine("Task 2: {0}", Thread.CurrentThread.ManagedThreadId);
      }
    );

  while (second.Status != TaskStatus.RanToCompletion)
  {
    Thread.Sleep(500);
    Console.WriteLine("Task {0} is {1}", first.Id, first.Status.ToString());
    Console.WriteLine("Task {0} is {1}", second.Id, second.Status.ToString());
  }
}

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