颤振Dart:从隔离中进行的计算管理获得的数据的正确方法是什么? [英] Flutter & Dart: What is the correct way to manage obtained data from a computation made in an Isolate?

查看:44
本文介绍了颤振Dart:从隔离中进行的计算管理获得的数据的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Dart中执行昂贵的计算时,强烈建议启动其他隔离.我知道,由于隔离区不共享任何状态,因此,如果要在隔离区之间建立通信,则可以使用

When doing expensive computations in Dart it is highly recommended to start up additional isolates. I know that, since isolates don't share any state, if you want to create communication between them, there is the possibility to pass a message from one to another by using SendPort and ReceivePort. However, when doing a computation in another Isolate, within the process of this new created isolate one could actually initialize an already created variable, for instance a variable of a Singleton, right?

所以我的问题是:这样可以继续吗?从隔离中进行的计算管理获得的数据的正确方法是什么?为什么?在新隔离区中进行计算时,我们是否应该总是只处理消息?

So my questions are: Is it okay to proceed like this? What is the correct way to manage obtained data from a computation made in an isolate and why? Should we always only work with messages when doing computations within new isolates?

推荐答案

否,您无法初始化来自其他隔离株的一个隔离株的变量.他们没有您提到的共享内存.隔离株之间唯一的通信方法是通过端口.

No, you cannot initialize a variable of one isolate from a different isolate. They don't have shared memory as you alluded to. The only method of communication between isolates is through ports.

即使分析器可能允许您在一个隔离变量中修改一个变量,您也不会得到预期的行为.隔离可以认为是完全不同的过程.

Even though the analyzer may allow to you to modify a variable in one isolate from another, you won't get the behavior you expect. Isolates can be thought of as entirely different processes.

我举了一个例子来展示这种行为:

I've made an example to show this behavior:

import 'dart:isolate';

Future<void> main(List<String> arguments) async {
  final single = Singleton();
  print(single.variable);

  single.variable = 1;
  print(single.variable);

  final port = ReceivePort();
  final isolate = await Isolate.spawn(isolateWork, port.sendPort);
  await for(dynamic message in port) {
    if(message == 'done') {
      isolate.kill();
      break;
    }
  }
}

void isolateWork(SendPort port) {
  final single = Singleton();
  print('In isolate: ${single.variable}');
  port.send('done');
}

class Singleton {
  int variable = 0;

  static final Singleton _singleton = Singleton._internal();

  factory Singleton() {
    return _singleton;
  }

  Singleton._internal();
}

这是一个简单的程序,它尝试使用单例来修改衍生自一个孤立变量中的变量.如果有共享内存,当我第一次获得单例时,可能会期望以下输出,打印默认的 variable 0 ,更改 variable 1 ,然后在隔离区中打印 variable :

This is a simple program that attempts to use a singleton to modify a variable in one isolate from a spawned one. If there were shared memory, one might expect the following output as I first obtain the singleton, print the default variable value of 0, change variable to 1, and then print variable in the isolate:

0
1
In isolate: 1

但是,由于这些隔离是完全独立的过程,因此生成的隔离具有其自己的单例实例,从而导致以下输出:

However, since these isolates are completely separate processes, the spawned isolate has its own instance of the singleton, leading to the following output:

0
1
In isolate: 0

在主隔离区中按预期方式打印了

0 1 ,但是生成的副本具有其自己的内存并使用单独的单例对象,因此它会打印0 ,即使它在主要隔离区中是 1 .

0 and 1 are printed as expected in the main isolate, but the spawned one has its own memory and uses a separate singleton object, so it prints 0 even though it's 1 in the main isolate.

如您在上面的示例中所见,我确实使用了端口,以便我的程序可以检测到隔离何时完成并优雅地终止进程.通过端口传递消息是在隔离之间传递数据的正确且唯一的方法.

As you can see in my example above, I did use ports so that my program could detect when the isolate was finished and gracefully kill the process. Passing messages with ports are the proper and only method of passing data between with isolates.

您将此问题标记为的问题,所以我猜您正在使用Flutter.如果您要使用单个输出执行单个大型计算,请使用Flutter的 compute 方法可能是使用隔离的最简单方法,因为它消除了使用端口的需要.但是,这可能会受到限制,并且像我在上面那样使用完全隔离的实现通常很有用.

You tagged this question as flutter, so I'm guessing you're using Flutter. If you're doing a single, large computation with a single output, using Flutter's compute method is probably the easiest way to use isolates as it removes the need for you to work with ports. However, it can be limiting and it's often useful to use a full isolate implementation like I did above.

这篇关于颤振Dart:从隔离中进行的计算管理获得的数据的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆