Scheduling tasks using Futures

The Dart VM is single-threaded, so all of an app's code runs in one thread, also called the main isolate. This is because main() is the function where Dart code starts executing an isolate, because Dart's concurrency model is based on isolates as separate processes that exchange messages. We will talk about isolates in depth in the coming recipes, but if your code doesn't start a new isolate, all of it runs in one isolate. But, in this one isolate, you can have lots of asynchronous pieces of code (let's call them tasks) running at the same time; in what order do they execute, and can we influence that order? It turns out that a better understanding of Dart's event loop and task queuing mechanism enables us to do that. This recipe will clarify Dart's scheduling mechanism and give you hints and tips for an ordered execution of tasks.

How to do it...

Have a look at the program tasks_scheduling.dart (the tasks are numbered consecutively and according to the way they are started):

import'dart:async';

main() {
  print('1) main task #1'),
  scheduleMicrotask(() => print('2) microtask #1'));
  newFuture.delayed(new Duration(seconds:1),
  () =>print('3) future #1 (delayed)'));
  new Future(() => print('4) future #2'));
  print('5) main task #2'),
  scheduleMicrotask(() => print('6) microtask #2'));
  new Future(() => print('7) future #3'))
  .then((_) => print('8) future #4'))
  .then((_) => print('9) future #5'))
  .whenComplete(cleanup);
  scheduleMicrotask(() => print('11) microtask #3'));
  print('12) main task #3'),
}

cleanup() {
  print('10) whenComplete #6'),
}

The following screenshot shows the output of the program, the order of which is explained in the next section:

How to do it...

How it works...

The main isolate proceeds as follows:

  1. First the code in main() is executed, line after line and synchronously.
  2. Then the event-loop mechanism kicks in, and this looks at the two queues in the system in the following order:
    • First, it takes a look at the microtask queue this queue is for all tasks that need to be executed before the event queue, for example, the changes that have to be done internally before the DOM starts rendering the modified screen. All of the tasks in this queue are executed before going to the following step.
    • Then, the event queue is handled, here, the tasks of all outside events, such as mouse events, drawing events, I/O, timers, messages between Dart isolates, and so on, are scheduled. Of course, in each queue, the tasks are handled one by one in the first in first out order.

Tip

While the event-loop is handling the microtask queue, no work is done on the event-queue, so the app can't draw or react to user events and seems effectively blocked. So, keep the microtask queue as short as possible. Preferably, put your tasks on the event queue.

In principle, when both queues are empty, the app can exit. Tasks (these are pieces of code to run later, asynchronously) can be scheduled using the following classes and methods from dart:async:

  1. Make a new Future object with a function to execute; this is appended to the event queue.
  2. With Future.delayed, you can specify the execution of a function to occur after a certain duration; this also goes to the event queue.
  3. Call the top-level scheduleMicrotask() function, which appends an item to the microtask queue.

Tip

Don't use a Timer class to schedule a task; this class has no facilities to catch exceptions, so an error during a timer task will blow up your app.

Chaining Futures in a series of then statements effectively ensures that they are executed in that order (see step 1 of the previous recipe). Also, a whencomplete clause will execute immediately after all the previous then statements.

So this is the order of execution: main(), then à microtask queue, then event queue, and then delayed tasks.

Tip

As a general best practice, don't put a compute-intensive task on either queue, but create that task in a separate isolate (or worker for a web app).

See also

  • See the upcoming recipes about isolates in this chapter, such as Using isolates in web apps and Using multiple cores with isolates
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset