4

I know Future will run in event queue.But event queue are also running on main isolate, if i do some heavy task (for example, calculate sum from 1 to 1000000) in future, it will block my ui code. But Future in network operation will not block ui (such as await httpClient.getUrl(uri)). Why does a network request using future take several seconds without blocking the UI, while computational operations block the UI?

@override
void initState() {
super.initState();
Future((){
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
  }
  print(result);
});

}

if i do some heavy task using Future in initState(), the ui will be blocked.

Turisla
  • 43
  • 1
  • 5

2 Answers2

4

Isolates in Dart are single-threaded. An isolate can do only one thing at a time.

Asynchronous functions are basically a form of cooperative multitasking. A function must yield (usually via await) to allow other operations to execute in the isolate.

Your computation doesn't yield, so it must run in its entirety before the UI can resume processing events, and the UI will be unresponsive. If you altered it:

Future(() async {
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
    await Future.delayed(Duration.zero);
  }
  print(result);
});

then you should find that the UI can process events regularly and should have the appearance of remaining responsive. (Note that your computation will take much longer to complete because of the additional extra overhead.)

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • @Turisla Huh. I guess I should have tried it first. I suspect that using `await null` doesn't work because although it defers execution, each iteration adds to the current [microtask queue](https://dart.dev/articles/archive/event-loop), which is processed synchronously before returning to the event loop. I've updated my answer. – jamesdlin Jun 27 '19 at 16:19
2

Let me answer briefly, the network request (HttpClient in dart:io) actually ended up in another isolate.

find _NativeSocket section inside socket_patch.dart file, keep searching down and you will see this statement (the link is likely to point to the wrong line as the SDK is constantly updated in the future):

_EventHandler._sendData(this, eventPort!.sendPort, fullData);

Does it look familiar?

rockyoung
  • 36
  • 4