23

I might have the wrong idea of Isolate and Future. Please help me to clear it up. Here is my understanding of both subjects.

Isolate: Isolates run code in its own event loop, and each event may run smaller tasks in a nested microtask queue.

Future: A Future is used to represent a potential value, or error, that will be available at some time in the future.

My confusions are:

  1. The doc says Isolate has it own loop? I feel like having its own event queue makes more sense to me, am I wrong?

  2. Is future running asynchronously on the main Isolate? I'm assuming future task actually got placed at the end of event queue so if it will be execute by loop in the future. Correct me if I'm wrong.

  3. Why use Isolate when there is future? I saw some examples using Isolate for some heavy task instead of Future. But why? It only makes sense to me when future execute asynchronously on the main isolate queue.

Suragch
  • 428,106
  • 278
  • 1,284
  • 1,317
Panda World
  • 1,400
  • 15
  • 25
  • 4
    Isolates are like threads. Futures aren't. So if you have expensive computation, a Future will still block the UI but an Isolate won't. – Rémi Rousselet Sep 25 '18 at 12:59

4 Answers4

20

A Future is a handle that allows you to get notified when async execution is completed. Async execution uses the event queue and code is executed concurrently within the same thread.

https://webdev.dartlang.org/articles/performance/event-loop

Dart code is by default executed in the root isolate.

You can start up additional isolates that usually run on another thread. An isolate can be either loaded from the same Dart code the root isolate was started with (with a different entry-point than main() https://api.dartlang.org/stable/2.0.0/dart-isolate/Isolate/spawn.html) or with different Dart code (loaded from some Dart file or URL https://api.dartlang.org/stable/2.0.0/dart-isolate/Isolate/spawnUri.html).

Isolates don't share any state and can only communicate using message passing (SendPort/ReceivePort). Each isolate has its own event queue.

https://webdev.dartlang.org/articles/performance/event-loop

Günter Zöchbauer
  • 558,509
  • 191
  • 1,911
  • 1,506
10

An Isolate runs Dart code on a single thread. Synchronous code like

print('hello');

is run immediately and can't be interrupted.

An Isolate also has an Event Loop that it uses to schedule asynchronous tasks on. Asynchronous doesn't mean that these tasks are run on a separate thread. They are still run on the same thread. Asynchronous just means that they are scheduled for later.

The Event Loop runs the tasks that are scheduled in what is called an Event Queue. You can put a task in the Event Queue by creating a future like this:

Future(() => print(hello));

The print(hello) task will get run when the other tasks ahead of it in the Event Queue have finished. All of this is happening on the same thread, that is, the same Isolate.

Some tasks don't get added to the Event Queue right away, for example

Future.delayed(Duration(seconds: 1), () => print('hello'));

which only gets added to the queue after a delay of one second.

So far everything I've been talking about gets done on the same thread, the same Isolate. Some work may actually get done on a different thread, though, like IO operations. The underlying framework takes care of that. If something expensive like reading from disk were done on the main Isolate thread then it would block the app until it finished. When the IO operation finishes the future completes and the update with the result is added to the Event Queue.

When you need to do CPU intensive operations yourself, you should run them on another isolate so that it doesn't cause jank in your app. The compute property is good for this. You still use a future, but this time the future is returning the result from a different Isolate.

Further study

Suragch
  • 428,106
  • 278
  • 1,284
  • 1,317
  • Is it okay to retrieve data from an isolate without ReceivePort and SendPort? Like for example, storing the obtained data into an already existing variable? – Iván Yoed Apr 20 '21 at 14:58
  • @IvánYoed, I haven't actually tried it, but theoretically it shouldn't work since isolates don't share memory. If you get that to work, though, I'd like to see your example. – Suragch Apr 21 '21 at 01:25
  • 1
    I've recently posted a question regarding this and received a good answer about it. Maybe it is of your interest https://stackoverflow.com/q/67181838/13766744 – Iván Yoed Apr 21 '21 at 03:04
9

In one sentence we could say,

Isolates: Dart is single-threaded but it is capable of doing multi-threading stuff using Isolates (many processes).

Future: Future is a result which is returned when dart has finished an asynchronous work. The work is generally done in that single-thread.

CopsOnRoad
  • 175,842
  • 51
  • 533
  • 380
3

Isolate could be compared to Thread even if dart is not multithreaded. It has it's own memory and event loop indeed, when Futures shares the same memory

Dart is able to spawn standalone processes, called Isolates (web workers in dart2js), which do not share memory when the main program, but are able to asynchronously, in another process (effectively a thread of sorts) is able to do computations without blocking the main thread.

A Future is run inside the Isolate that called it, not necesserally the main isolate.

I recommend this article which has better explanation than me.

Hadrien Lejard
  • 5,068
  • 2
  • 18
  • 18