6

質問をより明確にするために編集されました。

DartでIsolates(またはWebワーカー)と連携しようとしています。メインスレッドと分離スレッドの間で通信するために私が見つけることができる唯一の方法は、送信して呼び出し、次にメインスレッドから送信することです。しかし、これはメインスレッドが一部のデータを分離に渡すための優れた方法です。

分離株を情報を生成するものにしたい場合はどうなりますか?ワーカー内のすべての物理演算を実行し、更新された世界情報をメインスレッドに送信するゲームエンジンのように?JavaScriptでは、いつでもデータを送信できます。Dartに効率的な方法はありますか?それとも、メインスレッドから呼び出されるのを待ってから、メインスレッドに渡す必要がありますか?

PS私は疑問に思います、応答が完了するまでスレッドを呼び出してブロックしますか?

4

4 に答える 4

5

Dart 1.0以降、次のような分離を使用できます。

import 'dart:isolate';
import 'dart:async';

void doStuff(SendPort sendPort) {
  print('hi from inside isolate');
  ReceivePort receivePort = new ReceivePort();
  sendPort.send(receivePort.sendPort);

  receivePort.listen((msg) {
    print('Received in isolate: [$msg]');
    sendPort.send('ECHO: $msg');
  });

}

void main() {
  SendPort sendPort;

  ReceivePort receive = new ReceivePort();
  receive.listen((msg) {
    if (sendPort == null) {
      sendPort = msg;
    } else {
      print('From isolate: $msg');
    }
  });

  int counter = 0;

  Isolate.spawn(doStuff, receive.sendPort).then((isolate) {
    new Timer.periodic(const Duration(seconds:1), (t) {
      sendPort.send('Count is ${counter++}');
    });
  });
}
于 2014-01-20T03:57:43.353 に答える
3

警告:このコードは、非常に古いバージョンのDartでのみ機能します。Dart1.0以降では動作しません。

あなたが分離株にメッセージを投稿することに言及するように、あなたはそれのsendportのハンドルを持っている必要があります。

#import('dart:isolate');

main() {
  SendPort sendPort = spawnFunction(doWork);
  sendPort.call("hey 1").then((String res) => print("result was: [$res]"));
  sendPort.call("hey 2").then((String res) => print("result was: [$res]"));
}

doWork() {
  port.receive((msg, reply) {
    msg = "msg $msg";
    reply.send(msg);
  });
}

ただし、Dartメインスレッド自体は分離されているため、グローバルポート機能を使用してデータを送信できます。

#import('dart:isolate');
#import('dart:io');

main() {
   port.receive((data, reply) {
       // in here you can access objects created in the main thread
       print("handle [${data['text']}] for index ${data['index']}");
   });

   SendPort workPort = spawnFunction(doWork);
   workPort.send("msg", port.toSendPort());
}

doWork() {
   port.receive((msg, reply) {
      int i = 0;
      new Timer.repeating(1000, (Timer timer) {
         i++;
         var data = {
            "text": "$msg $i",
            "index": i
         };
         print("sending $data");
         reply.send(data);
      });
   });
}

分離株間で送受信できるものには一定の制限があり、現在、分離株はJSとVMで異なる動作をすることに注意してください。現在の制限については、ここで詳しく説明しています。

于 2012-04-24T21:22:51.623 に答える
1

これは、親が2つの分離を作成し、次に2つの分離も親プロセスとともに相互に通信する例です。

親コード:

import 'dart:isolate';
import 'dart:html';
import 'dart:async';

main() {
  querySelector('#output').text = 'Your Dart app is running.';
  int counter = 0;

  // Parent - Child 1
  SendPort csendPort1;
  ReceivePort receivePort1 = new ReceivePort();
  // Parent - Child 2
  SendPort csendPort2;
  ReceivePort receivePort2 = new ReceivePort();
  // Child1 - Child2
  SendPort csendPort11;
  SendPort csendPort12;

  // Child 1
  receivePort1.listen((msg) {
    if (csendPort1 == null) {
      csendPort1 = msg;
    } else if (csendPort11 == null) {
      csendPort11 = msg;
    } else {
      print('$msg');`enter code here`
    }
  });

  bool child1 = false;
  Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort1.sendPort).then((isolate) {
    print('Child 1 isolate spawned');
    new Timer.periodic(const Duration(milliseconds: 500), (t) {
      if (csendPort11 != null && csendPort12 != null && child1 == false) {
        child1 = true;
        csendPort12.send(csendPort11);
      } else {
        csendPort1.send('Parent-Child1: ${counter++}');
      }
    });
  });

  // Child 2
  receivePort2.listen((msg) {
    if (csendPort2 == null) {
      csendPort2 = msg;
    } else if (csendPort12 == null) {
      csendPort12 = msg;
    } else {
      print('$msg');
    }
  });

  bool child2 = false;
  Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort2.sendPort).then((isolate) {
    print('Child 2 isolate spawned');
    new Timer.periodic(const Duration(milliseconds: 500), (t) {
      if (csendPort11 != null && csendPort12 != null && child2 == false) {
        child2 = true;
        csendPort11.send(csendPort12);
      } else {
        csendPort2.send('Parent-Child2: ${counter++}');
      }
    });
  });
}

子コード:

import 'dart:isolate';
import 'dart:async';

int pcounter = 0;
int ccounter = 0;

SendPort csendPort;
void handleTimeout() {
  csendPort.send("${ccounter++}");
}

main(List<String> args, SendPort psendPort) {
  // Parent Comm
  ReceivePort creceivePort1 = new ReceivePort();
  psendPort.send(creceivePort1.sendPort);

  creceivePort1.listen((msg) {
    psendPort.send('Child-Parent: ${pcounter++} - ${msg}');
  });

  // Child-Child Comm
  ReceivePort creceivePort2 = new ReceivePort();
  psendPort.send(creceivePort2.sendPort);

  creceivePort2.listen((msg) {
    if (csendPort == null) {
      csendPort = msg;
      csendPort.send("${ccounter++}");
    } else {
      print("Child-Child: $msg");
      var duration = const Duration(milliseconds: 2000);
      new Timer(duration, handleTimeout);
    }
  });
}

HTMLコード:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="scaffolded-by" content="https://github.com/google/stagehand">
    <title>WebIsolateTest</title>
    <link rel="stylesheet" href="styles.css">
    <script defer src="main.dart" type="application/dart"></script>
    <script defer src="packages/browser/dart.js"></script>
</head>

<body>

  <div id="output"></div>

</body>
</html>
于 2016-03-07T18:32:47.387 に答える
0

これで、 MessageBoxクラスを使用して逆の通信を行うことができます。このコードは、MessageBoxのシンクエンドを受信するとすぐにIsolateコードからメッセージを送信します。メインスレッドは、Isolateから送信されたメッセージを受信し、Dartiumのコンソールに出力します。シンクを受け取ったら、ゲームロジックを起動し、受け取ったシンクオブジェクトを使用して更新を送信できます。

import 'dart:html';
import 'dart:isolate';

void main() {
  IsolateSink isolateSink = streamSpawnFunction(myIsolateEntryPoint);
  MessageBox isolateMessageBox = new MessageBox();
  isolateSink.add(isolateMessageBox.sink);
  isolateMessageBox.stream.listen((String data) {
    print(data);
  });
}

void myIsolateEntryPoint() {
  stream.listen((IsolateSink messageBoxSink) {
    messageBoxSink.add("Test");
  });
}
于 2013-07-22T10:24:49.180 に答える