[英]Dart Future: when throwing Error, the the main thread is interrupted, but in Flutter it's not
I tried to test the behavior of future, but我试图测试未来的行为,但是
Throwing an exception in future will break the dart main thread将来抛出异常会破坏飞镖主线程
However, the reverse is true in the Flutter:然而,在 Flutter 中情况正好相反:
Dart Code飞镖代码
Future(() async {
await Future.delayed(Duration(seconds: 10));
print("TimeOut");
}).timeout(Duration(seconds: 5));
Future(() async {
await Future.delayed(Duration(seconds: 15));
print("AAAAAAA");
});
in Dart use the code dart run ./a.dart
在 Dart 中使用代码dart run ./a.dart
Unhandled exception:
TimeoutException after 0:00:05.000000: Future not completed
in Flutter:在颤振中:
E/flutter (11789): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: TimeoutException after 0:00:05.000000: Future not completed
E/flutter (11789):
I/flutter (11789): TimeOut
I/flutter (11789): AAAAAAA
Why ?为什么 ?
The difference between Dart and Flutter is that Flutter catches all unhandled exceptions and just prints them out (including the stack trace). Dart 和 Flutter 之间的区别在于,Flutter 会捕获所有未处理的异常并将它们打印出来(包括堆栈跟踪)。 This is on purpose and the secret is that Flutter registers a callback to the static class function FlutterError.onError and the default implementation is the function FlutterError.presentError .这是故意的,秘诀在于 Flutter 向静态类函数FlutterError.onError注册了一个回调,默认实现是函数FlutterError.presentError 。 Some more details on the official docs: Handling errors in Flutter有关官方文档的更多详细信息: Flutter 中的处理错误
It's possible to disable terminating the app/script on fatal errors by calling Isolate.setErrorsFatal with false
.可以通过使用false
调用Isolate.setErrorsFatal来禁用在致命错误时终止应用程序/脚本。 For example, to keep async code running even if an unhandled exception is thrown just do this.例如,即使抛出未处理的异常也要保持异步代码运行,只需执行此操作即可。
void main () {
Isolate.current.setErrorsFatal(false); // <- Here
Future(() async {
await Future.delayed(Duration(seconds: 10));
print("TimeOut");
}).timeout(Duration(seconds: 5));
Future(() async {
await Future.delayed(Duration(seconds: 15));
print("AAAAAAA");
});
}
And the output is going to be:输出将是:
TimeOut
AAAAAAA
The following code simulates the same thing Flutter does in Dart with runZonedGuarded :以下代码模拟了 Flutter 在 Dart 中使用runZonedGuarded所做的相同事情:
import 'dart:async';
void main(List<String> args) {
runZonedGuarded(program, errorHandler);
}
void program() {
Future(() async {
await Future.delayed(Duration(seconds: 10));
print("TimeOut");
}).timeout(Duration(seconds: 5));
Future(() async {
await Future.delayed(Duration(seconds: 15));
print("AAAAAAA");
});
}
void errorHandler(Object error, StackTrace stack) {
print('Unhandled exception:\n$error');
}
The output is going to be the following in Dart: Dart 中的输出将如下所示:
Unhandled exception:
TimeoutException after 0:00:05.000000: Future not completed
TimeOut
AAAAAAA
On the other hand, it's possible to do the same thing in Flutter as Dart does.另一方面,在 Flutter 中也可以像 Dart 一样做同样的事情。 Ie kills the app on whenever unhandled exception.即在出现未处理的异常时终止应用程序。 It's just a matter of using the runZonedGuarded again:这只是再次使用runZonedGuarded的问题:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
void main() {
runZonedGuarded(() async {
runApp(const MyApp());
}, (Object error, StackTrace stack) {
print('Unhandled exception:\n$error');
exit(1);
});
}
void program() {
Future(() async {
await Future.delayed(Duration(seconds: 10));
print("TimeOut");
}).timeout(Duration(seconds: 5));
Future(() async {
await Future.delayed(Duration(seconds: 15));
print("AAAAAAA");
});
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
program();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, child) => const Scaffold(
body: Center(child: Text('The app is going to exit in 5 seconds...')),
),
);
}
}
The output is going to be the following:输出将如下所示:
flutter: Unhandled exception:
TimeoutException after 0:00:05.000000: Future not completed
Lost connection to device.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.