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

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

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

}<br />

}<br />

catch (Exception ex)<br />

{<br />

workItem.TaskSource.SetException (ex);<br />

}<br />

In EnqueueTask, we enqueue a work item which encapsulates the target delegate and<br />

a task completion source—which lets us later control the task that we return to the<br />

consumer.<br />

In Consume, we first check whether a task has been canceled after dequeuing the work<br />

item. If not, we run the delegate and then call SetResult on the task completion<br />

source to indicate its completion.<br />

Here’s how we can use this class:<br />

var pcQ = new PCQueue (1);<br />

Task task = pcQ.EnqueueTask (() => Console.WriteLine ("Easy!"));<br />

...<br />

We can now wait on task, perform continuations on it, have exceptions propagate<br />

to continuations on parent tasks, and so on. In other words, we’ve got the richness<br />

of the task model while, in effect, implementing our own scheduler.<br />

SpinLock and SpinWait<br />

In parallel programming, a brief episode of spinning is often preferable to blocking,<br />

as it avoids the cost of context switching and kernel transitions. SpinLock and Spin<br />

Wait are designed to help in such cases. Their main use is in writing custom synchronization<br />

constructs.<br />

SpinLock<br />

SpinLock and SpinWait are structs and not classes! This design<br />

decision was an extreme optimization technique to avoid the<br />

cost of indirection and garbage collection. It means that you<br />

must be careful not to unintentionally copy instances—by passing<br />

them to another method without the ref modifier, for instance,<br />

or declaring them as readonly fields. This is particularly<br />

important in the case of SpinLock.<br />

The SpinLock struct lets you lock without incurring the cost of a context switch, at<br />

the expense of keeping a thread spinning (uselessly busy). This approach is valid in<br />

high-contention scenarios when locking will be very brief (e.g., in writing a threadsafe<br />

linked list from scratch).<br />

920 | Chapter 22: Parallel Programming

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

Saved successfully!

Ooh no, something went wrong!