【问题标题】:Access variables in external scope when using isolation in Dart在 Dart 中使用隔离时访问外部范围内的变量
【发布时间】:2023-01-09 23:29:34
【问题描述】:

在 Isolates 中,我可以引用外部作用域中的局部变量或类的字段变量,而无需将其作为单独的消息传递。
这是将值隐式复制到新隔离的内存区域吗?
我很好奇细节。

例子

class Person {
  Person(this._baseNum);

  /// access [_baseNum] in isolate
  final int _baseNum;
  int age = 0;

  /// access [extraAge] in isolate
  Future<void> addAge(int extraAge) async {
    final mainReceivePort = ReceivePort();

    await Isolate.spawn((SendPort sendPort) async {
      sendPort.send(await _calcAge(_baseNum, extraAge));
    }, mainReceivePort.sendPort);

    age = await mainReceivePort.first;
    mainReceivePort.close();
  }

  static Future<int> _calcAge(int someNum, int age) async {
    // ... heavy work ...
    return age + someNum;
  }
}

// ...

void main() {
  test('test', () async {
    final p = Person(10);
    await p.addAge(3);
    expect(p.age, 13);
  });
}

【问题讨论】:

    标签: flutter dart dart-isolates


    【解决方案1】:

    在 Isolates 中,我可以引用外部作用域中的局部变量或类的字段变量,而无需将其作为单独的消息传递。

    这是将值隐式复制到新隔离的内存区域吗?

    是的。

    证明这一点的一种方法是,如果您从外部范围或字段变量中获取这些变量之一,并更新隔离中的值。您会看到,从隔离区外部看,该值不会更新。这是因为他们正在处理变量的独立副本。

    import 'dart:isolate';
    import 'package:test/test.dart';
    
    class Person {
      Person(this._baseNum);
    
      /// access [_baseNum] in isolate
      int _baseNum;
      int age = 0;
    
      /// access [extraAge] in isolate
      Future<void> addAge(int extraAge) async {
        final mainReceivePort = ReceivePort();
    
        await Isolate.spawn((SendPort sendPort) async {
          _baseNum++; // modify _baseNum
          sendPort.send(await _calcAge(_baseNum, extraAge));
        }, mainReceivePort.sendPort);
    
        age = await mainReceivePort.first;
        mainReceivePort.close();
      }
    
      static Future<int> _calcAge(int someNum, int age) async {
        // ... heavy work ...
        return age + someNum;
      }
    }
    
    // ...
    
    void main() {
      test('test', () async {
        final p = Person(10);
        await p.addAge(3);
        expect(p.age, 14);
        expect(p._baseNum, 10); // _baseNum still 10 despite _baseNum++ in isolate
      });
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多