15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

502 ❘ ChaPTer 20 threAds, tAsks, And synchrOnizAtiOn<br />

scheduler that the task takes a long time, so the scheduler will more likely use a new thread. If the task<br />

should be attached to the parent task <strong>and</strong>, thus, should be canceled if the parent were canceled, set the<br />

option AttachToParent. The value PreferFairness means that the scheduler should take first tasks<br />

that are already waiting. That’s not the default case if a task is created within another task. If tasks create<br />

additional work using child tasks, child tasks are preferred to other tasks. They are not waiting last in the<br />

thread pool queue for the work to be done. If these tasks should be h<strong>and</strong>led in a fair manner to all other<br />

tasks, set the option to PreferFairness.<br />

Continuation Tasks<br />

Task t4 = new Task(TaskMethod, TaskCreationOptions.PreferFairness);<br />

t4.Start();<br />

With tasks, you can specify that after a task is finished another specific task should start to run, for<br />

example, a new task that uses a result from the previous one or that should do some cleanup if the previous<br />

task failed.<br />

Whereas the task h<strong>and</strong>ler has either no parameter or one object parameter, the continuation h<strong>and</strong>ler has a<br />

parameter of type Task. Here, you can access information about the originating task.<br />

static void DoOnFirst()<br />

{<br />

Console.WriteLine("doing some task {0}", Task.CurrentId);<br />

Thread.Sleep(3000);<br />

}<br />

static void DoOnSecond(Task t)<br />

{<br />

Console.WriteLine("task {0} finished", t.Id);<br />

Console.WriteLine("this task id {0}", Task.CurrentId);<br />

Console.WriteLine("do some cleanup");<br />

Thread.Sleep(3000);<br />

}<br />

code snippet TaskSamples/Program.cs<br />

A continuation task is defined by invoking the ContinueWith method on a task. You could also use the<br />

TaskFactory for this. t1.OnContinueWith(DoOnSecond) means that a new task invoking the method<br />

DoOnSecond() should be started as soon as the task t1 is finished. You can start multiple tasks when<br />

one task is finished, <strong>and</strong> a continuation task can also have another continuation task, as this example<br />

demonstrates.<br />

Task t1 = new Task(DoOnFirst);<br />

Task t2 = t1.ContinueWith(DoOnSecond);<br />

Task t3 = t1.ContinueWith(DoOnSecond);<br />

Task t4 = t2.ContinueWith(DoOnSecond);<br />

The continuation tasks so far were always started when the previous task was finished, no matter<br />

how the previous task was finished. With values from TaskContinuationOptions, you can define<br />

that a continuation task should only start if the originating task was successful (or faulted). Some<br />

of the possible values are OnlyOnFaulted, NotOnFaulted, OnlyOnCanceled, NotOnCanceled, <strong>and</strong><br />

OnlyOnRanToCompletion.<br />

Task hierarchies<br />

Task t5 = t1.ContinueWith(DoOnError,<br />

TaskContinuationOptions.OnlyOnFaulted);<br />

With task continuations, one task is started after another. Tasks can also form a hierarchy. When a task<br />

itself starts a new task, a parent/child hierarchy is started.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!