Я хочу убедиться, что длительная работа изолятов может вызвать ANR (приложение не отвечает) во Flutter. Для этого я загрузил флаттер-код и создал кнопку, которая при нажатии будет выполнять очень длительную операцию (на другом изоляте), которая, как я ожидаю, заблокирует основной изолят, из-за чего приложение перестанет отвечать. Я видел, что Future.delayed использует Timer внутри себя, поэтому и Timer, и Future работают на разных изолятах, но приложение по-прежнему полностью отзывчиво.
Ожидаемое поведение: длительно работающие изоляты, запускаемые при нажатии кнопки, должны останавливать выполнение основного изолята (который обновляет пользовательский интерфейс). Наблюдаемое поведение: пользовательский интерфейс полностью отзывчив, несмотря на то, что существуют другие долгоработающие изолированные приложения.
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
ElevatedButton(
child: const Text("Press me to Trigger ANR"),
onPressed: () {
Timer(const Duration(seconds: 10), () {
debugPrint('Now 10 seconds ANR is over.');
}); //---------------------> This is not causing ANR
//Future.delayed(const Duration(seconds: 30), () {
// debugPrint('Now 30 seconds ANR is over.');
//}); ---------------------> This also does not cause ANR
},
),
],
),
Хорошо, теперь я понял. onPressed() не запускает другой изолят, а просто помещает событие в очередь событий текущего изолята. Я неправильно понял это. Спасибо. Обратный вызов таймера и будущего выполняется только по истечении указанного времени в том же изоляте. Но почему ожидание завершения этого таймера не приводит к приостановке изоляции main(UI)? Подобно подсчету 10 или 30 секунд, это также событие, которое необходимо выполнить в одном и том же цикле событий.





Чтобы вызвать ошибку «Приложение не отвечает» (ANR) во Flutter, вам необходимо заблокировать цикл событий основного изолята. Использование Timer или Future.delayed не приведет к ошибке ANR, поскольку они выполняются асинхронно и не блокируют основной изолятор.
Вот как можно смоделировать длительную операцию на основном изоляте, которая может его заблокировать и вызвать ошибку ANR:
Код, который вы опубликовали, будет работать в основном изоляте. Чтобы выполнить расчет в отдельном изоляте, вам придется использовать
Isolate.run()или создать новый изолят. См. docs.flutter.dev/perf/isolates