Skip to content

Day 05 Introduction to TPL

Kobi Hari edited this page Oct 28, 2020 · 1 revision

Day 05 - Introduction to TPL

Projects:

Fun With Tasks Introduction to Tasks and TPL

About Processes, Threads and App Domains

  • We talked about process, as a way for the operating system to allow multiple programs to run
  • We talked about the way a process allocates memory to the program
  • We talked about Threads, as a way to execute code.
  • We talked about App Domains as a middle entity between process and thread, that allows to run multiple programs in the same process, by dividing the memory between the applications while sharing the thread pool and some other resources

Threads in .Net Framework

  • Threads are operating system entities that run code.
  • Each thread has an allocated stack, but all threads share the same heap, so the different threads have access to the same memory in additional to a private stack.
  • You can create a new thread and run a delegate in it, but this is considered bad practice:
    • Thread allocation consumes time and memory
    • The more threads there are, the more time in takes to manage them.
  • Modren approaches favor thread pooling, which is why .net comes with a Thread Pool with reusable threads.
    • You can send a delegate (a work item) to the thread pool
    • The thread pool has a global queue for work items
    • The thread pool creates new threads according to the workload
    • Each thread also has its own queue and the thread pool sends the delegate to the selected thread's queue.
    • The thread pool then uses some additional logic to spread the work items smartly between the threads.

TPL - Task Parallel Library

  • Task is a container of information, it does not run code.
  • Task is a container of information, only! it does not run code!!!
  • Task object only holds information about the completion of a... well... task.
  • Task Members:
    • Status - In Progress, Completed, or Failed. Notice that it does not care if the task has started, only if it has ended
    • Result - In completed, the result of the task.
  • The task data is not meant to be pulled, but rather Pushed.
  • You can sign up for the task by using the ContinueWith method. This method accepts a delegate, along with other parameters, and runs the delegate upon completion of the task.

TPL - Demo

  • We talk briefly about WPF, XAML and the thread structure of UI frameworks (single main thread that has sole access to the UI, along with thread pool background threads that can not access UI objects)
  • We built a small application that takes about 6 seconds to calculate all the prime numbers between 1 and 180000
  • We saw that if we perform the caluclations on the main thread, the UI freezes in the meantime
  • We used Task.Factory.StartNew in order to pass a delegate to the thread pool and create a task over that delegate
  • We used Task.ContinueWith to schedule continuation to the task to be run upon completion
  • We saw that by default, the continuation runs in the thread pool as well, which caused an exception when we tried to modify UI objects
  • We saw that we can tell the continuation to run in the same thread that created the task, by using TaskScheduler.FromCurrentSynchronizationContext
  • We agreed that using these methods explicitly is cumbersome.

Async-Await

  • We understood that the keywords async and await basically tell the compiler to split the method into several methods, and then schedule each part as a continuation of a task
  • The async keyword is reqruired in order to tell the compiler that the await keyword is going to be used in the body of the method
  • The await keyword splits the method, and everything that comes after it becomes a continuation method
  • The method finishes at the first await and returns synchronously to the caller
  • We saw that ContinueWith returns a task that describes the completion of the continuation
  • We saw that async methods do the same thing.
  • We saw the difference between calling an async method with await, and without.
  • We talked about Task exception and how important it is to make sure they are awaited so the exceptions are caught and treated.

Task Exceptions

  • We continuted to investigate how exceptions work with tasks.
  • We learned about the AggregateException class that is returned by tasks and understood that the exceptions are always aggragated bacause the task itself is a hierarchic concept
  • We used InnerException and InnerExceptions properties to get the exceptions that were actually thrown in the task
  • We used the Flatten method to convert the exception hierarchy into a flat list
  • We saw that async await catches the first inner exception, not the aggregate exeption, but we can still access the original exception by using the original task and reading from Task.Exception property