(event handling) • Progress Indication Responsiveness • Servers have crazy numbers of cores • Almost every desktop/laptop has multiple 4 or 8 cores • Even phones are dual and quad core now Performance
Scheduling ◦ Continuation Options Task passed to the continuation ◦ firstTask.ContinueWith((task) => DoMoreStuff(task.result)); Whenever this task completes (Success, Cancel, or Error) do this other action (or function)
or event. var tcs = new TaskCompletionSource() if (e.Cancelled) tcs.TrySetCanceled(); else if (e.Error != null) tcs.TrySetException(e.Error); else //GetData tcs.TrySetResult(data)
from detached tasks must be handled or rethrown in the immediate parent task; they are not propagated back to the calling thread in the same way as attached child tasks propagated back. The topmost parent can manually rethrow an exception from a detached child to cause it to be wrapped in an AggregateException and propagated back to the joining thread. (stolen from MSDN documentation)
is the list. try { task1.Wait(); //or task1.result } catch (AggregateException ae) { foreach (var e in ae.Flatten().InnerExceptions) { if (e is MyCustomException) { //Handle } } }
Cancellation Token ◦ Give your tasks a pager (the token) ◦ The same token source is a number for that pager ◦ Token.Cancel signals the task to return (doesn’t actually bring the task back) ◦ Tasks can get more than one pager with a LinkedToken ◦ Call cancel on a WhenAny to cancel the unfinished tasks Cancellation Timeout ◦ Automatically call if tasks with this pager have not completed yet ◦ When creating the token or later on
◦ Check when you get started (In case you were waiting for resources for a while) ◦ The check has a cost, but should be checked regularly for long running task Dealing with cancellation in the task ◦ ThrowIfCancellationRequested() ◦ OperationCanceledException ◦ CancellationToken.IsCancellationRequested ◦ Something else based on the context or domain
only permits it. • Run each iteration as a different task Parallel.For/ForEach • Use the default or build one that suits the data and task type Partitioner • Cancellation Token • Max Degree of Parallelism • Task Scheduler Options
must be thread safe for the actions in the query Some query constructions will always fall back to sequential execution, more in .NET 4 than in 4.5. In 4.5 only ElementAt() and “Positional” extensions will always be sequential
any type that implements IProducerConsumerCollection<T>. ConcurrentDictionary<TKey, TValue> Thread-safe implementation of a dictionary of key-value pairs. ConcurrentQueue<T> Thread-safe implementation of a FIFO (first-in, first-out) queue. ConcurrentStack<T> Thread-safe implementation of a LIFO (last-in, first-out) stack. ConcurrentBag<T> Thread-safe implementation of an unordered collection of elements. IProducerConsumerCollection<T> The interface that a type must implement to be used in a BlockingCollection.
to work on an algorithm in parallel by providing a point at which each task can signal its arrival and then block until some or all tasks have arrived CountdownEvent Simplifies fork and join scenarios by providing an easy join mechanism ManualResetEventSlim Like ManualResetEvent, but can only be used within a process SemaphoreSlim Like Semaphore, but doesn’t wrap the Win32 Semaphore SpinLock A mutual exclusion lock primitive that causes the thread that is trying to acquire the lock to spin for a period of time before yielding its quantum. SpinLock offers better performance than other forms of locking if the wait time is short SpinWait A small, lightweight type that will spin for a specified time and eventually put the thread into a wait state if the spin count is exceeded
work-stealing algorithm to help make sure that no threads are sitting idle while others still have work in their queues. When a thread-pool thread is ready for more work, it first looks at the head of its local queue, then in the global queue, and then in the local queues of other threads WPF Synchronization Context Demo
“less than void” ◦ Use only for top level event handlers The hidden exception – ◦ Either handle sub tasks exceptions in the current task ◦ Or attach the task as a child task Impatient Code – ◦ Ensure that you aren’t just waiting on starting a task ◦ ConfigureAwait(false);