15.01.2013 Views

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

A safe pattern is to rethrow antecedent exceptions. As long as the continuation is<br />

Waited upon, the exception will be propagated and rethrown to the Waiter:<br />

Task continuation = Task.Factory.StartNew (() => { throw null; })<br />

.ContinueWith (ant =><br />

{<br />

if (ant.Exception != null) throw ant.Exception;<br />

// Continue processing...<br />

});<br />

continuation.Wait(); // Exception is now thrown back to caller.<br />

Another way to deal with exceptions is to specify different continuations for exceptional<br />

versus nonexceptional outcomes. This is done with TaskContinuationOptions:<br />

Task task1 = Task.Factory.StartNew (() => { throw null; });<br />

Task error = task1.ContinueWith (ant => Console.Write (ant.Exception),<br />

TaskContinuationOptions.OnlyOnFaulted);<br />

Task ok = task1.ContinueWith (ant => Console.Write ("Success!"),<br />

TaskContinuationOptions.NotOnFaulted);<br />

This pattern is particularly useful in conjunction with child tasks, as we’ll see very<br />

soon.<br />

The following extension method “swallows” a task’s unhandled exceptions:<br />

public static void IgnoreExceptions (this Task task)<br />

{<br />

task.ContinueWith (t => { var ignore = t.Exception; },<br />

TaskContinuationOptions.OnlyOnFaulted);<br />

}<br />

(This could be improved by adding code to log the exception.) Here’s how it would<br />

be used:<br />

Task.Factory.StartNew (() => { throw null; }).IgnoreExceptions();<br />

Continuations and child tasks<br />

A powerful feature of continuations is that they kick off only when all child tasks<br />

have completed (see Figure 22-5). At that point, any exceptions thrown by the children<br />

are marshaled to the continuation.<br />

In the following example, we start three child tasks, each throwing a NullReferen<br />

ceException. We then catch all of them in one fell swoop via a continuation on the<br />

parent:<br />

TaskCreationOptions atp = TaskCreationOptions.AttachedToParent;<br />

Task.Factory.StartNew (() =><br />

{<br />

Task.Factory.StartNew (() => { throw null; }, atp);<br />

Task.Factory.StartNew (() => { throw null; }, atp);<br />

Task.Factory.StartNew (() => { throw null; }, atp);<br />

})<br />

.ContinueWith (p => Console.WriteLine (p.Exception),<br />

TaskContinuationOptions.OnlyOnFaulted);<br />

906 | Chapter 22: Parallel Programming

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

Saved successfully!

Ooh no, something went wrong!