Using System.Threading.Tasks.Task
- in the TPL there are only two abstractions that are being exposed: Task and Parallel (which are replicable tasks) and all other abstractions are built on top of these two
- the System.Threading.Parallel class is useful for solving common data and task parallel problems
- it is implemented on top of the lower-level System.Threading.Tasks.Task class, which can be used directly to solve parallel problems with greater flexibility and control over the way work is partitioned
- Task queues work in a similar manner as the ThreadPool
Example: comparing the similarity in calling the Task and ThreadPool as both code snippets cause the provided delegate to be queued for asynchronous execution – but that is where the similarity ends
// using the ThreadPool
ThreadPool.QueueUserWorkItem(delegate { ... });
// using Task
Task.Create(delegate { ... });
- with the ThreadPool, referencing a queued work item in order to do things like wait on it is a manual and laborious process
- the Task class makes this operation much simpler
Example: NOTE: between the creation point of the task and the point you call Wait(), the action will be potentially executed in parallel
// [1] to create a task, call the static Create
// method and pass in and Action delegate
// which deals with the work to be done
static Task Create (Action action);
// [2] to the get the results of the work, call Wait
void Wait();
- the static Create methods return a Task object that represents the newly created asynchronous operation and this instance then provides methods such as Wait
- so why the executed potentially in parallel and not a guaranteed parallelism?
- the TPL is for speeding up a lot of work on multiple cores but it is not about fairness or asynchronous programming
- as a programmer you are exposing potential parallelism in that the computations can be speeded up but the library does not guarantee this parallelism because it would imply a heavier weight mechanism in its design and implementation
Example: want to execute three methods and wait for them to complete
Task t1 = Task.Create(delegate { A(); });
Task t2 = Task.Create(delegate { B(); });
Task t3 = Task.Create(delegate { C(); });
t1.Wait();
t2.Wait();
t3.Wait();
// can replace t1-t2.Wait with WaitAll
Task.WaitAll(t1,t2,t3)
// it can be made even simpler using the
// Parallel.Invoke as it takes an array of actions
Parallel.Invoke(() => A(), () => B(), () => C());
- unlike the Invoke method, however, using the Task class directly allows for control over how the Task instances are created (using various overloads of Task.Create )
- it also allows for work to be done between the asynchronous invocations of each of the methods
- Task also provides cancellation support
- calling Cancel on a Task may remove the Task from the scheduler’s queue if the Task has not already begun execution
- for reliability reasons, if the Task has started execution, it will not be aborted
- instead, its IsCancelled property will be set to return true, which the Task itself can check during execution at periodic intervals
- the static Task.Current property will return the currently executing Task
No comments:
Post a Comment