3

私は Dart もプログラミングもまったく初めてです。アイソレートを使用して Dart でコマンドラインプログラムを開発しようとしています。私の意図は、そのパフォーマンスを同じプログラムと比較することですが、スレッドを使用して Java で記述されています。

これまでのところ、Dart プログラムは次のようになっています。

  1. main.dart

    import "dart:async";
    import "dart:isolate";
    
    main() {    
        var rPort1 = new ReceivePort();
        var rPort2 = new ReceivePort();
    
        var p1 = 0;
        rPort1.listen((partial) {
            print("p1 ${partial}");
            p1 = partial;
            rPort1.close();
        });
        var p2 = 0;
        rPort2.listen((partial) {
           print("p2 ${partial}");
           p2 = partial;
           rPort2.close();
        });
    
        Isolate.spawnUri(new Uri.file("MyIsolate.dart"), [arg0, ...], rPort1.sendPort);
        Isolate.spawnUri(new Uri.file("MyIsolate.dart"), [arg0, ...], rPort2.sendPort);
    
        var p3 = p1 + p2;
        print("p3 ${p3}");
    }
    
  2. myIsolate.dart

    import "dart:async";
    import "dart:isolate";
    
    main(args, SendPort port) {
        var partial = 0;
        // ... do stuff ...
        // args are used and partial is updated
        port.send(partial);
    }
    

出力は次のようになります。

p3 0
p1 -0.1168096561671553
p2 0.023709338284264223

ご覧のとおり、各アイソレートの戻り値は、メインのアイソレートの実行が終了した後に返されます。私が望むのは、アイソレートの結果を使用して、メインでさらに計算することです。

何が欠けているのかわからない。私は非常にばかげていると確信していますが、この問題を進めることはできません。Java では、各スレッドの結果値を取得するのは簡単ですが、Dart では分離でこれを行う方法を理解できません。

何か案は?

4

2 に答える 2

3

(ポートからの) すべてのストリームが完了するまで待つ必要があります。それを行う方法の1つは、次のようなものです。

import "dart:async";
import "dart:isolate";

main() {
  var rPort1 = new ReceivePort();
  var rPort2 = new ReceivePort();

  // Defining completers which would complete when Streams are finished   
  Completer c1 = new Completer();
  Completer c2 = new Completer();

  var p1 = 0;
  rPort1.listen((partial) {
    print("p1 ${partial}");
    p1 = partial;
    rPort1.close();
  }, onDone: ()=>c1.complete()); // Notice onDone callback here
  var p2 = 0;
  rPort2.listen((partial) {
    print("p2 ${partial}");
    p2 = partial;
    rPort2.close();

  }, onDone: ()=>c2.complete()); // And here

  Isolate.spawnUri(new Uri.file("my_isolate.dart"), [0], rPort1.sendPort);
  Isolate.spawnUri(new Uri.file("my_isolate.dart"), [0], rPort2.sendPort);

  // Waiting for both streams to complete before summing our results
  Future.wait([c1.future,c2.future]).then((_){
    var p3 = p1 + p2;
    print("p3 ${p3}");
  });
}

あなたのタスクでは、正確な値を待っている場合は、必要なこれらの値の Future のみを定義し、Isolate (およびそのストリーム) が終了するのを待たずにそれらを完了することができます。

c*.complete(<value>)これを行うには、対応する listen() コールバックに移動するだけです。そのようなもの(テストされていません):

rPort1.listen((partial) {
  print("p1 ${partial}");
  c1.complete(partial);
  rPort1.close();
});
rPort2.listen((partial) {
  print("p2 ${partial}");
  c2.complete(partial);
  rPort2.close();
});

...

Future.wait([c1.future,c2.future]).then((result){
  var p3 = result[0] + result[1];
  print("p3 ${p3}");
});
于 2015-06-24T04:54:33.200 に答える