4

にはspawnUri(uri)関数がありますがdart:isolate、例が見つかりません。私はその使用法を推測しましたが、失敗しました。

2 つのファイルがあるとします。最初のファイルで 2 番目のファイルを呼び出しspawnUri、通信します。

最初のダーツ

import "dart:isolate";

main() {
  ReceivePort port = new ReceivePort();
  port.receive((msg, _) {
    print(msg);
    port.close();
  });
   var c = spawnUri("./second.dart");
   c.send(["Freewind", "enjoy dart"], port.toSendPort());
}

秒ダーツ

String hello(String who, String message) {
   return "Hello, $who, $message";
}

void isolateMain(ReceivePort port) {
  port.receive((msg, reply) => reply.send(hello(msg[0], msg[1]));
}

main() {}

しかし、この例は機能しません。正しいコードがわからないのですが、どうすれば修正できますか?

4

4 に答える 4

2

警告: このコードは古くなっています。

second.dartを次のように置き換えて機能させます。

import "dart:isolate";

String hello(String who, String message) {
  return "Hello, $who, $message";
}

main() {
  port.receive((msg, reply) => reply.send(hello(msg[0], msg[1])));
}
于 2013-06-25T14:39:10.763 に答える
1

Dart Web Developmentからコピーされた恥知らずな › Isolate.spawn の使用例 作者が気にしないことを願っています

スポーンされた分離株は、親にどこでどのように応答するかわかりません。

親では、子の分離からすべてのメッセージを受信する ReceivePort を作成できます。アイソレートをスポーンするときはいつでも、(Isolate.spawn のメッセージ引数を介して) ReceivePort から SendPort インスタンスを渡します。

子アイソレートは、メッセージを受信できるように、独自の ReceivePort も作成する必要があります。インスタンス化されると、子のisolateは、(親のSendPortを介して)親に(自身のReceivePortから)独自のSendPortを送信する必要があります。

現在の API は、それ自体ではまったく役に立ちません。しかし、本格的な実装に必要なすべてのビルディング ブロックを提供します。

次の行に沿って、メッセージをヘッダー内にラップする必要がある場合があります。

class _Request {
  /// The ID of the request so the response may be associated to the request's future completer.
  final Capability requestId;
  /// The SendPort we must respond to, because the message could come from any isolate.
  final SendPort   responsePort;
  /// The actual message of the request.
  final dynamic    message

  const _Request(this.requestId, this.responsePort, this.message);
}

class _Response {
  /// The ID of the request this response is meant to.
  final Capability requestId;
  /// Indicates if the request succeeded.
  final bool       success;
  /// If [success] is true, holds the response message.
  /// Otherwise, holds the error that occured.
  final dynamic    message;

  const _Response.ok(this.requestId, this.message): success = true;
  const _Response.error(this.requestId, this.message): success = false;
}

すべてのisolateは、次のようなシングルトン メッセージ バスを持つことができます:

final isolateBus = new IsolateBus();

class IsolateBus {
  final ReceivePort _receivePort = new ReceivePort();
  final Map<Capability, Completer> _completers = {};

  IsolateBus() {
    _receivePort.listen(_handleMessage, onError: _handleError);
  }

  void _handleMessage(portMessage) {
    if (portMessage is _Request) {
      // This is a request, we should process.
      // Here we send back the same message
      portMessage.responsePort.send(
        new _Response.ok(portMessage.requestId, portMessage.message));

    } else if (portMessage is _Response) {
      // We received a response
      final completer = _completers[portMessage.requestId];
      if (completer == null) {
        print("Invalid request ID received.");
      } else if (portMessage.success) {
        completer.complete(portMessage.message);
      } else {
        completer.completeError(portMessage.message);
      }

    } else {
      print("Invalid message received:  $portMessage");
    }
  }

  void _handleError(error) {
    print("A ReceivePort error occured:   $error");
  }

  Future request(SendPort port, message) {
    final completer = new Completer();
    final requestId = new Capability();
    _completers[requestId] = completer;

    port.send(new _Request(requestId, _receivePort.sendPort, message));

    return completer.future;
  }
}

SendPort anotherIsolatePort = ...
isolateBus.request(anotherIsolatePort, "Some message");

これは、アーキテクチャの一例にすぎません。もちろん、独自に展開することもできます。これは、通知 (応答のない要求)、ストリームなどをサポートするように拡張できます。

すべての分離からのすべての SendPort インスタンスを追跡し、最終的にそれらをサービスとして登録するには、グローバルな分離レジストリが必要になる場合があります。

于 2014-08-03T11:52:09.133 に答える
1

この要点: https://gist.github.com/damondouglas/8620350は、動作する (私がテストした) Dart 1.5 の例を提供します。例Isolate.spawn(...)もそこにあります。

ここで再現(インポートステートメントを追加):

echo.dart:

import 'dart:isolate';
void main(List<String> args, SendPort replyTo) {
  replyTo.send(args[0]);
}

main.dart:

import 'dart:isolate';
import 'dart:async';
main() {
  var response = new ReceivePort();
  Future<Isolate> remote = Isolate.spawnUri(Uri.parse("echo.dart"), ["foo"], response.sendPort);
  remote.then((_) => response.first)
    .then((msg) { print("received: $msg"); });
}
于 2014-08-03T11:48:23.000 に答える