What Will I Learn?
- You will learn about Concurrency in Dart
- You will learn about Parallel programming in Dart
- You will learn how to use Futures to perform Asynchronous Evaluations in Dart
- You will learn about Completers
- You will learn how to Spawn an Isolate
- You will learn how to use Ports to Send and Receive Messages
OS Support for Dart:
- The Dart SDK
- A Dart supported text editor (Dart Pad can be used)
- A little time to sit and watch a video and some patience to learn the language
Resources for Dart:
- Dart Website: https://www.dartlang.org/
- Dart Official Documentation: https://www.dartlang.org/guides/language/language-tour
- Dart GitHub repository: https://github.com/dart-lang/sdk
- Awesome Dart GitHub Repository: https://github.com/yissachar/awesome-dart
- Pub website: https://pub.dartlang.org
Dart Logo (Google): https://www.dartlang.org/
In this Dart Video Tutorial, we take a look at how we can preform Concurrency and Parallel programming in Dart. We take a look at Futures and Completers. We also look at Isolates and their Ports and Messages. We talk about why Asynchronous Evaluation is necessary and powerful and we talk about the difference between Parallel programming and Asynchronous programming.
Using Futures and Completers to Preform Asynchronous Tasks
Often when dealing with systems that are outside of the control of your current program; you have to deal with task that may take unspecified amounts of time to complete. If you run these tasks in a synchronous manner, they block the code that follows the execution of the task. This becomes a problem especially when dealing with computations that might fail or might take very long periods of time. To overcome this problem, Dart exposes a Future API that uses Completer Objects to define when the task has completed. These Futures allow Dart to specify Events which are pushed into an external Queue. When the Completer object comes back with a completion, the Future then wraps the result of this completion and serves it where it is needed.
The above Graph highlights Dart's main execution loop. Dart is a single threaded programming language and when a program starts it checks two main queues. It first checks a microtask queue to see if there are any scheduled microtasks. If there are, then it will execute those microtasks and loop back to re-check the queue. If there are none, then the execution will move to the Event queue. This Event queue is where Futures get logged and queued for execution. Dart executes the Event and then moves back to check to see if there are any Microtasks and Events in the Queues before finishing its execution once the Queues are empty.
Creating Parallel code with Dart using Isolates
Dart is inherently a single threaded programming language. The main execution loop allows the program to work with asynchronous code but another thread is needed to create parallel code. This is where the concept of the Isolate comes into play. Each isolate is another instance of the same execution loop that was highlighted above. These instances do not share memory between one another and can only communicate using messages. These messages are passed through unidirectional Ports which means that an Isolate can only either send data to another Isolate or receive data from another Isolate.
Above is a graph that showcases the general concept behind isolates. Isolate One which is the main isolate spawns isolate two in this case and it does so at the very beginning of execution. Both isolates have identical execution lifecycles with different microtasks and events depending on the tasks that have been assigned to them by the developers. Both have their own Event and Microtask Queues which allows these isolates to deal with Asynchronous code. Isolate Two sends messages to Isolate One and it does this through a Port. Inside of Isolate Two a Send Port Object and inside of Isolate One is a Receive Port Object. These two objects facilitate the message passing between these two Isolates.
The Source Code for this video may be found here: https://github.com/tensor-programming/dart_for_beginners/tree/tensor-programming-patch-7
- A Beginners Guide to Dart - Generics, Exceptions, Factory Constructors, and Enumerated Types - Part Seven
- A Beginners Guide to Dart - Scope, Iterators, Functional Programming and Collections - Part Six
- A Beginners Guide to Dart - Inheritance, Abstract Classes, Interfaces, Mixins and Casting - Part Five
- A Beginners Guide to Dart - Methods, Final, Static, and Class Inheritance - Part Four
- A Beginners Guide to Dart - Intro to Classes and Objects - Part Three
- A Beginners Guide to Dart - Control Flow and Low Level Compilation - Part Two
- A Beginners Guide to Dart - Types, Functions, Variables and Objects - Part One