Introduction to Tasks


The entire Task parallel Library is based on the concept of Tasks. Tasks are basically Objects containing an operation. ‘Tasks’ are exactly what you would do in real life. An operation that need to be carried out. Like everything in .NET, Task is just a class. MSDN defines it saying a class that represents an asynchronous operation.

First we need to include the namespace, System.Threading.Tasks

clip_image001

So the syntax is as shown. So what happens when the compiler encounters T.start() ?.

The compiler forks the current thread and spawns a child thread that executes the new task. The thread is dedicated to the task until the task completes which is when the control exits the code block supplied to the task. The current thread continues executing the statements that are present after T.start() in its own thread. We have used the term UI thread as in a windows application the main thread is the UI thread.

Now in case of a single Core machine the UI thread and the Worker thread all run on the same core. But in a multicore machine, the threads actually run on two different cores which enables us to do Parallel Processing.

Now its time to dabble with codes.

So , I have a demo, which basically calculates the value of PI to to the 107 digits ! It uses Gauss-Legendre algorithm. While it is not as fast as some of the more modern algorithms it does have the advantage of being understandable. Basically any resource intensive operation would have sufficed.

Now I have first coded the sequential code .I have made a Windows Application and put in ,

   1: private void button1_Click(object sender, EventArgs e)

   2:  

   3: {

   4:  

   5: int start_Time = System.Environment.TickCount;

   6:  

   7: double j =calculatePi(10000000);

   8:  

   9: int stop_Time = System.Environment.TickCount;

  10:  

  11: int seconds = stop_Time - start_Time;

  12:  

  13: textBox1.Text = j.ToString();

  14:  

  15: label1.Text = seconds.ToString();

  16:  

  17: }

  18:  

  19: public int calculatePi(int dig)

  20:  

  21: {

  22:  

  23: //some resource intensive operation!...If you want to see this part download the code!!!

  24:  

  25: }

  26:  

  27: return 1;

  28:  

  29: }

In the UI , I have a label, which displays the milliseconds passed. In my machine , it shows a little over 7000 milliseconds . Now if you run this program in your machine, you will see the app will freeze and won’t even allow the button animation to complete. The app cannot be dragged by the mouse.Only after 7 seconds when the operation finishes , can you fiddle with the app again.

So what do we do ? We change the code into tasks.

   1: private void button2_Click(object sender, EventArgs e)

   2:  

   3: {

   4:  

   5: Task T = new Task ( ()=> {

   6:  

   7: int start_Time = System.Environment.TickCount;

   8:  

   9: int j=calculatePi(10000000);

  10:  

  11: int stop_Time = System.Environment.TickCount;

  12:  

  13: int seconds = stop_Time - start_Time;

  14:  

  15: this.textBox1.Text = j.ToString();

  16:  

  17: this.label2.Text = seconds.ToString();

  18:  

  19: });

  20:  

  21: T.Start();

  22:  

  23: }

  24:  

The app looks like

clip_image002

A fairly simple app in which our button 2 is the “Parallel” button. We have put our entire code inside tasks . Fore newbies,you might get startled seeing the “()=>”. These are called Lambda s a feature of the c# Language which are nothing but anonymous delegates. To understand working of the Tasks, read my previous article on Closures and Lambdas .

So when we run the app and click on parallel, we will see that our app is responsive,we can drag it around,the buttons are working but there is an EXCEPTION!!!!

clip_image004

The exception states that its an InvalidOperationException and that was due to “ Cross-thread operation not valid: Control textBox1 accessed from a thread other than the thread it was created on”

So what does the error mean ? And why did we get the error?

Refer to my previous diagram, where I said when the compiler encounters T.start() it forks the thread .So at the moment there is one UI thread and the Task thread.UI thread contains the references to the UI elements. The task which is being executed on another thread does not know about the state of the UI. Hence unless I am on the UI thread ,I cannot reference the UI!!.

So how do we fix it ??

That is on the next part!!

Advertisements

One response to “Introduction to Tasks

  1. Pingback: Asynchronous Programming Series « Using Abhik.Mitra.myThoughts;

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s