I know Dart is Single Threaded, flutter is also, so if I do some heavy task, it will block the UI event queue, but a network request takes several seconds without blocking the UI.
so, why Socket does not block UI? What bothers me is why the socket does not block the UI, but the heavy task does, Although they all asynchronous task.
for example, this code will block UI
@override
void initState() {
super.initState();
Future((){
var result;
for (var i = 0; i < 1000000; ++i) {
result = 'result is $i';
}
print(result);
});
this code is normal HTTP request,it won't block UI
get() async {
var httpClient = new HttpClient();
var uri = new Uri.http(
'example.com', '/path1/path2', {'param1': '42', 'param2': 'foo'});
var request = await httpClient.getUrl(uri);
var response = await request.close();
var responseBody = await response.transform(UTF8.decoder).join();
}
The reason why the socket does not block the UI is to split the request process into multiple parts? and send these part to the current microtask queue,As this answer says:
https://stackoverflow.com/a/56783713/6540631
so, does anyone know how sockets are implemented asynchronously? Whether socket use Isolate, Future, or other means?The socket run on UI thread, or other thread?
and, If I have to perform heavy tasks that cannot be split in the UI thread(such as text layout), what should I do?
Supplementary explanation:
I know how to use Future and Isolate, but I encountered a problem.
if use TextPainter.layout in isolate will get a compiler error native function not found.
I need layout many words and it takes a long time (100ms+), it will block UI thread.
What should I do?
https://github.com/flutter/flutter/issues/30604
The Flutter engine native APIs for the UI package is only available in the primary isolate.
https://github.com/flutter/flutter/issues/30604#issuecomment-481380706
right now you would have to write your own line-breaking logic - perhaps as a plugin. We don't currently have any API for doing text layout in a separate isolate. @GaryQian might have some other idea about this too.
https://github.com/flutter/flutter/issues/30604#issuecomment-526013977
so I have to do text layout in UI thread(use TextPainter ), although write a plugin can solve this problem and it work well, Is there an easier way?
I guess I can get help from the implementation details of the socket, so I raised this question.
Await calls are non-blocking. The way this works is, while Dart is single-threaded, some Dart code delegate their implementation to the Dart VM. Things like file reads or HTTP requests are performed outside of Dart (either by the browser or in c++), in a different thread.
As per this answer and this article, await is supposed to interrupt code execution and actually wait for the future to complete and then continue executing the rest of the code sequentially. It also suggests that this might block the main thread, which is only logical in that case.
In dart, Network calls are asnycronous
nature and returns Future
. When anything is asynchronous
, it runs in the background and returns result or response on task completion. It's quite similar to Promise
in javascript. Here are list of key terms related to Async in dart taken from Official Docs.
Key terms:
Future
but function must yield via await to allow other operations to execute in the isolate. If you don't yield, it will block the UI thread. That's exactly you got in the first code block and UI gone blocked. You have used Future
but the computation still goes synchronous in it. There is a precise Post here for more reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With